| // ignore-tidy-file-filelength | |
| use std::borrow::Cow; | |
| use std::path::PathBuf; | |
| use rustc_ast::token::{self, InvisibleOrigin, MetaVarKind, Token}; | |
| use rustc_ast_pretty::pprust; | |
| use rustc_errors::codes::*; | |
| use rustc_errors::{ | |
| Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, | |
| Level, Subdiagnostic, SuggestionStyle, msg, | |
| }; | |
| use rustc_macros::{Diagnostic, Subdiagnostic}; | |
| use rustc_span::edition::{Edition, LATEST_STABLE_EDITION}; | |
| use rustc_span::{Ident, Span, Symbol}; | |
| #[derive(Diagnostic)] | |
| #[diag("ambiguous `+` in a type")] | |
| pub(crate) struct AmbiguousPlus { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub suggestion: AddParen, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected a path on the left-hand side of `+`", code = E0178)] | |
| pub(crate) struct BadTypePlus { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sub: BadTypePlusSub, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion("try adding parentheses", applicability = "machine-applicable")] | |
| pub(crate) struct AddParen { | |
| #[suggestion_part(code = "(")] | |
| pub lo: Span, | |
| #[suggestion_part(code = ")")] | |
| pub hi: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum BadTypePlusSub { | |
| AddParen { | |
| #[subdiagnostic] | |
| suggestion: AddParen, | |
| }, | |
| #[label("perhaps you forgot parentheses?")] | |
| ForgotParen { | |
| #[primary_span] | |
| span: Span, | |
| }, | |
| #[label("expected a path")] | |
| ExpectPath { | |
| #[primary_span] | |
| span: Span, | |
| }, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("missing angle brackets in associated item path")] | |
| pub(crate) struct BadQPathStage2 { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub wrap: WrapType, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("inherent impls cannot be {$modifier_name}")] | |
| #[note("only trait implementations may be annotated with `{$modifier}`")] | |
| pub(crate) struct TraitImplModifierInInherentImpl { | |
| #[primary_span] | |
| pub span: Span, | |
| pub modifier: &'static str, | |
| pub modifier_name: &'static str, | |
| #[label("{$modifier_name} because of this")] | |
| pub modifier_span: Span, | |
| #[label("inherent impl for this type")] | |
| pub self_ty: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "types that don't start with an identifier need to be surrounded with angle brackets in qualified paths", | |
| applicability = "machine-applicable" | |
| )] | |
| pub(crate) struct WrapType { | |
| #[suggestion_part(code = "<")] | |
| pub lo: Span, | |
| #[suggestion_part(code = ">")] | |
| pub hi: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected item, found `;`")] | |
| pub(crate) struct IncorrectSemicolon<'a> { | |
| #[primary_span] | |
| #[suggestion( | |
| "remove this semicolon", | |
| style = "verbose", | |
| code = "", | |
| applicability = "machine-applicable" | |
| )] | |
| pub span: Span, | |
| #[help("{$name} declarations are not followed by a semicolon")] | |
| pub show_help: bool, | |
| pub name: &'a str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("incorrect use of `await`")] | |
| pub(crate) struct IncorrectUseOfAwait { | |
| #[primary_span] | |
| #[suggestion( | |
| "`await` is not a method call, remove the parentheses", | |
| style = "verbose", | |
| code = "", | |
| applicability = "machine-applicable" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("incorrect use of `use`")] | |
| pub(crate) struct IncorrectUseOfUse { | |
| #[primary_span] | |
| #[suggestion( | |
| "`use` is not a method call, try removing the parentheses", | |
| style = "verbose", | |
| code = "", | |
| applicability = "machine-applicable" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion("`await` is a postfix operation", applicability = "machine-applicable")] | |
| pub(crate) struct AwaitSuggestion { | |
| #[suggestion_part(code = "")] | |
| pub removal: Span, | |
| #[suggestion_part(code = ".await{question_mark}")] | |
| pub dot_await: Span, | |
| pub question_mark: &'static str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("incorrect use of `await`")] | |
| pub(crate) struct IncorrectAwait { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub suggestion: AwaitSuggestion, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected iterable, found keyword `in`")] | |
| pub(crate) struct InInTypo { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "remove the duplicated `in`", | |
| code = "", | |
| style = "verbose", | |
| applicability = "machine-applicable" | |
| )] | |
| pub sugg_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("invalid variable declaration")] | |
| pub(crate) struct InvalidVariableDeclaration { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sub: InvalidVariableDeclarationSub, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum InvalidVariableDeclarationSub { | |
| #[suggestion( | |
| "switch the order of `mut` and `let`", | |
| style = "verbose", | |
| applicability = "maybe-incorrect", | |
| code = "let mut" | |
| )] | |
| SwitchMutLetOrder(#[primary_span] Span), | |
| #[suggestion( | |
| "missing keyword", | |
| applicability = "machine-applicable", | |
| style = "verbose", | |
| code = "let mut" | |
| )] | |
| MissingLet(#[primary_span] Span), | |
| #[suggestion( | |
| "write `let` instead of `auto` to introduce a new variable", | |
| style = "verbose", | |
| applicability = "machine-applicable", | |
| code = "let" | |
| )] | |
| UseLetNotAuto(#[primary_span] Span), | |
| #[suggestion( | |
| "write `let` instead of `var` to introduce a new variable", | |
| style = "verbose", | |
| applicability = "machine-applicable", | |
| code = "let" | |
| )] | |
| UseLetNotVar(#[primary_span] Span), | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("switch the order of `ref` and `box`")] | |
| pub(crate) struct SwitchRefBoxOrder { | |
| #[primary_span] | |
| #[suggestion( | |
| "swap them", | |
| applicability = "machine-applicable", | |
| style = "verbose", | |
| code = "box ref" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("invalid comparison operator `{$invalid}`")] | |
| pub(crate) struct InvalidComparisonOperator { | |
| #[primary_span] | |
| pub span: Span, | |
| pub invalid: String, | |
| #[subdiagnostic] | |
| pub sub: InvalidComparisonOperatorSub, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum InvalidComparisonOperatorSub { | |
| #[suggestion( | |
| "`{$invalid}` is not a valid comparison operator, use `{$correct}`", | |
| style = "verbose", | |
| applicability = "machine-applicable", | |
| code = "{correct}" | |
| )] | |
| Correctable { | |
| #[primary_span] | |
| span: Span, | |
| invalid: String, | |
| correct: String, | |
| }, | |
| #[label("`<=>` is not a valid comparison operator, use `std::cmp::Ordering`")] | |
| Spaceship(#[primary_span] Span), | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`{$incorrect}` is not a logical operator")] | |
| #[note("unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators")] | |
| pub(crate) struct InvalidLogicalOperator { | |
| #[primary_span] | |
| pub span: Span, | |
| pub incorrect: String, | |
| #[subdiagnostic] | |
| pub sub: InvalidLogicalOperatorSub, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum InvalidLogicalOperatorSub { | |
| #[suggestion( | |
| "use `&&` to perform logical conjunction", | |
| style = "verbose", | |
| applicability = "machine-applicable", | |
| code = "&&" | |
| )] | |
| Conjunction(#[primary_span] Span), | |
| #[suggestion( | |
| "use `||` to perform logical disjunction", | |
| style = "verbose", | |
| applicability = "machine-applicable", | |
| code = "||" | |
| )] | |
| Disjunction(#[primary_span] Span), | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`~` cannot be used as a unary operator")] | |
| pub(crate) struct TildeAsUnaryOperator( | |
| #[primary_span] | |
| #[suggestion( | |
| "use `!` to perform bitwise not", | |
| style = "verbose", | |
| applicability = "machine-applicable", | |
| code = "!" | |
| )] | |
| pub Span, | |
| ); | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected {$negated_desc} after identifier")] | |
| pub(crate) struct NotAsNegationOperator { | |
| #[primary_span] | |
| pub negated: Span, | |
| pub negated_desc: String, | |
| #[subdiagnostic] | |
| pub sub: NotAsNegationOperatorSub, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum NotAsNegationOperatorSub { | |
| #[suggestion( | |
| "use `!` to perform logical negation or bitwise not", | |
| style = "verbose", | |
| applicability = "machine-applicable", | |
| code = "!" | |
| )] | |
| SuggestNotDefault(#[primary_span] Span), | |
| #[suggestion( | |
| "use `!` to perform bitwise not", | |
| style = "verbose", | |
| applicability = "machine-applicable", | |
| code = "!" | |
| )] | |
| SuggestNotBitwise(#[primary_span] Span), | |
| #[suggestion( | |
| "use `!` to perform logical negation", | |
| style = "verbose", | |
| applicability = "machine-applicable", | |
| code = "!" | |
| )] | |
| SuggestNotLogical(#[primary_span] Span), | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("malformed loop label")] | |
| pub(crate) struct MalformedLoopLabel { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "use the correct loop label format", | |
| applicability = "machine-applicable", | |
| code = "'", | |
| style = "verbose" | |
| )] | |
| pub suggestion: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("borrow expressions cannot be annotated with lifetimes")] | |
| pub(crate) struct LifetimeInBorrowExpression { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "remove the lifetime annotation", | |
| applicability = "machine-applicable", | |
| code = "", | |
| style = "verbose" | |
| )] | |
| #[label("annotated with lifetime here")] | |
| pub lifetime_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("field expressions cannot have generic arguments")] | |
| pub(crate) struct FieldExpressionWithGeneric(#[primary_span] pub Span); | |
| #[derive(Diagnostic)] | |
| #[diag("macros cannot use qualified paths")] | |
| pub(crate) struct MacroInvocationWithQualifiedPath(#[primary_span] pub Span); | |
| #[derive(Diagnostic)] | |
| #[diag("expected `while`, `for`, `loop` or `{\"{\"}` after a label")] | |
| pub(crate) struct UnexpectedTokenAfterLabel { | |
| #[primary_span] | |
| #[label("expected `while`, `for`, `loop` or `{\"{\"}` after a label")] | |
| pub span: Span, | |
| #[suggestion("consider removing the label", style = "verbose", code = "")] | |
| pub remove_label: Option<Span>, | |
| #[subdiagnostic] | |
| pub enclose_in_block: Option<UnexpectedTokenAfterLabelSugg>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "consider enclosing expression in a block", | |
| applicability = "machine-applicable" | |
| )] | |
| pub(crate) struct UnexpectedTokenAfterLabelSugg { | |
| #[suggestion_part(code = "{{ ")] | |
| pub left: Span, | |
| #[suggestion_part(code = " }}")] | |
| pub right: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("labeled expression must be followed by `:`")] | |
| #[note("labels are used before loops and blocks, allowing e.g., `break 'label` to them")] | |
| pub(crate) struct RequireColonAfterLabeledExpression { | |
| #[primary_span] | |
| pub span: Span, | |
| #[label("the label")] | |
| pub label: Span, | |
| #[suggestion( | |
| "add `:` after the label", | |
| style = "verbose", | |
| applicability = "machine-applicable", | |
| code = ": " | |
| )] | |
| pub label_end: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("found removed `do catch` syntax")] | |
| #[note("following RFC #2388, the new non-placeholder syntax is `try`")] | |
| pub(crate) struct DoCatchSyntaxRemoved { | |
| #[primary_span] | |
| #[suggestion( | |
| "replace with the new syntax", | |
| applicability = "machine-applicable", | |
| code = "try", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("float literals must have an integer part")] | |
| pub(crate) struct FloatLiteralRequiresIntegerPart { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "must have an integer part", | |
| applicability = "machine-applicable", | |
| code = "0", | |
| style = "verbose" | |
| )] | |
| pub suggestion: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected `;`, found `[`")] | |
| pub(crate) struct MissingSemicolonBeforeArray { | |
| #[primary_span] | |
| pub open_delim: Span, | |
| #[suggestion( | |
| "consider adding `;` here", | |
| style = "verbose", | |
| applicability = "maybe-incorrect", | |
| code = ";" | |
| )] | |
| pub semicolon: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected `..`, found `...`")] | |
| pub(crate) struct MissingDotDot { | |
| #[primary_span] | |
| pub token_span: Span, | |
| #[suggestion( | |
| "use `..` to fill in the rest of the fields", | |
| applicability = "maybe-incorrect", | |
| code = "..", | |
| style = "verbose" | |
| )] | |
| pub sugg_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("cannot use a `block` macro fragment here")] | |
| pub(crate) struct InvalidBlockMacroSegment { | |
| #[primary_span] | |
| pub span: Span, | |
| #[label("the `block` fragment is within this context")] | |
| pub context: Span, | |
| #[subdiagnostic] | |
| pub wrap: WrapInExplicitBlock, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion("wrap this in another block", applicability = "machine-applicable")] | |
| pub(crate) struct WrapInExplicitBlock { | |
| #[suggestion_part(code = "{{ ")] | |
| pub lo: Span, | |
| #[suggestion_part(code = " }}")] | |
| pub hi: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("this `if` expression is missing a block after the condition")] | |
| pub(crate) struct IfExpressionMissingThenBlock { | |
| #[primary_span] | |
| pub if_span: Span, | |
| #[subdiagnostic] | |
| pub missing_then_block_sub: IfExpressionMissingThenBlockSub, | |
| #[subdiagnostic] | |
| pub let_else_sub: Option<IfExpressionLetSomeSub>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum IfExpressionMissingThenBlockSub { | |
| #[help("this binary operation is possibly unfinished")] | |
| UnfinishedCondition(#[primary_span] Span), | |
| #[help("add a block here")] | |
| AddThenBlock(#[primary_span] Span), | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("Rust has no ternary operator")] | |
| pub(crate) struct TernaryOperator { | |
| #[primary_span] | |
| pub span: Span, | |
| /// If we have a span for the condition expression, suggest the if/else | |
| #[subdiagnostic] | |
| pub sugg: Option<TernaryOperatorSuggestion>, | |
| /// Otherwise, just print the suggestion message | |
| #[help("use an `if-else` expression instead")] | |
| pub no_sugg: bool, | |
| } | |
| #[derive(Subdiagnostic, Copy, Clone)] | |
| #[multipart_suggestion( | |
| "use an `if-else` expression instead", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| pub(crate) struct TernaryOperatorSuggestion { | |
| #[suggestion_part(code = "if ")] | |
| pub before_cond: Span, | |
| #[suggestion_part(code = "{{")] | |
| pub question: Span, | |
| #[suggestion_part(code = "}} else {{")] | |
| pub colon: Span, | |
| #[suggestion_part(code = " }}")] | |
| pub end: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[suggestion( | |
| "remove the `if` if you meant to write a `let...else` statement", | |
| applicability = "maybe-incorrect", | |
| code = "", | |
| style = "verbose" | |
| )] | |
| pub(crate) struct IfExpressionLetSomeSub { | |
| #[primary_span] | |
| pub if_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("missing condition for `if` expression")] | |
| pub(crate) struct IfExpressionMissingCondition { | |
| #[primary_span] | |
| #[label("expected condition here")] | |
| pub if_span: Span, | |
| #[label( | |
| "if this block is the condition of the `if` expression, then it must be followed by another block" | |
| )] | |
| pub block_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected expression, found `let` statement")] | |
| #[note("only supported directly in conditions of `if` and `while` expressions")] | |
| pub(crate) struct ExpectedExpressionFoundLet { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub reason: ForbiddenLetReason, | |
| #[subdiagnostic] | |
| pub missing_let: Option<MaybeMissingLet>, | |
| #[subdiagnostic] | |
| pub comparison: Option<MaybeComparison>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("let-chain with missing `let`")] | |
| pub(crate) struct LetChainMissingLet { | |
| #[primary_span] | |
| pub span: Span, | |
| #[label("expected `let` expression, found assignment")] | |
| pub label_span: Span, | |
| #[label("let expression later in the condition")] | |
| pub rhs_span: Span, | |
| #[suggestion( | |
| "add `let` before the expression", | |
| applicability = "maybe-incorrect", | |
| code = "let ", | |
| style = "verbose" | |
| )] | |
| pub sug_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`||` operators are not supported in let chain conditions")] | |
| pub(crate) struct OrInLetChain { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Subdiagnostic, Clone, Copy)] | |
| #[multipart_suggestion( | |
| "you might have meant to continue the let-chain", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| pub(crate) struct MaybeMissingLet { | |
| #[suggestion_part(code = "let ")] | |
| pub span: Span, | |
| } | |
| #[derive(Subdiagnostic, Clone, Copy)] | |
| #[multipart_suggestion( | |
| "you might have meant to compare for equality", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| pub(crate) struct MaybeComparison { | |
| #[suggestion_part(code = "=")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected `=`, found `==`")] | |
| pub(crate) struct ExpectedEqForLetExpr { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "consider using `=` here", | |
| applicability = "maybe-incorrect", | |
| code = "=", | |
| style = "verbose" | |
| )] | |
| pub sugg_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected `{\"{\"}`, found {$first_tok}")] | |
| pub(crate) struct ExpectedElseBlock { | |
| #[primary_span] | |
| pub first_tok_span: Span, | |
| pub first_tok: String, | |
| #[label("expected an `if` or a block after this `else`")] | |
| pub else_span: Span, | |
| #[suggestion( | |
| "add an `if` if this is the condition of a chained `else if` statement", | |
| applicability = "maybe-incorrect", | |
| code = "if ", | |
| style = "verbose" | |
| )] | |
| pub condition_start: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected one of `,`, `:`, or `{\"}\"}`, found `{$token}`")] | |
| pub(crate) struct ExpectedStructField { | |
| #[primary_span] | |
| #[label("expected one of `,`, `:`, or `{\"}\"}`")] | |
| pub span: Span, | |
| pub token: Cow<'static, str>, | |
| #[label("while parsing this struct field")] | |
| pub ident_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("outer attributes are not allowed on `if` and `else` branches")] | |
| pub(crate) struct OuterAttributeNotAllowedOnIfElse { | |
| #[primary_span] | |
| pub last: Span, | |
| #[label("the attributes are attached to this branch")] | |
| pub branch_span: Span, | |
| #[label("the branch belongs to this `{$ctx}`")] | |
| pub ctx_span: Span, | |
| pub ctx: String, | |
| #[suggestion( | |
| "remove the attributes", | |
| applicability = "machine-applicable", | |
| code = "", | |
| style = "verbose" | |
| )] | |
| pub attributes: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("missing `in` in `for` loop")] | |
| pub(crate) struct MissingInInForLoop { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sub: Option<MissingInInForLoopSub>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum MissingInInForLoopSub { | |
| // User wrote `for pat of expr {}` | |
| // Has been misleading, at least in the past (closed Issue #48492), thus maybe-incorrect | |
| #[suggestion( | |
| "try using `in` here instead", | |
| style = "verbose", | |
| applicability = "maybe-incorrect", | |
| code = "in" | |
| )] | |
| InNotOf(#[primary_span] Span), | |
| // User wrote `for pat = expr {}` | |
| #[suggestion( | |
| "try using `in` here instead", | |
| style = "verbose", | |
| applicability = "maybe-incorrect", | |
| code = "in" | |
| )] | |
| InNotEq(#[primary_span] Span), | |
| #[suggestion( | |
| "try adding `in` here", | |
| style = "verbose", | |
| applicability = "maybe-incorrect", | |
| code = " in " | |
| )] | |
| AddIn(#[primary_span] Span), | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("missing expression to iterate on in `for` loop")] | |
| pub(crate) struct MissingExpressionInForLoop { | |
| #[primary_span] | |
| #[suggestion( | |
| "try adding an expression to the `for` loop", | |
| code = "/* expression */ ", | |
| applicability = "has-placeholders", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`{$loop_kind}...else` loops are not supported")] | |
| #[note( | |
| "consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run" | |
| )] | |
| pub(crate) struct LoopElseNotSupported { | |
| #[primary_span] | |
| pub span: Span, | |
| pub loop_kind: &'static str, | |
| #[label("`else` is attached to this loop")] | |
| pub loop_kw: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected `,` following `match` arm")] | |
| pub(crate) struct MissingCommaAfterMatchArm { | |
| #[primary_span] | |
| #[suggestion( | |
| "missing a comma here to end this `match` arm", | |
| applicability = "machine-applicable", | |
| code = ",", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("keyword `catch` cannot follow a `try` block")] | |
| #[help("try using `match` on the result of the `try` block instead")] | |
| pub(crate) struct CatchAfterTry { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("cannot use a comma after the base struct")] | |
| #[note("the base struct must always be the last field")] | |
| pub(crate) struct CommaAfterBaseStruct { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "remove this comma", | |
| style = "verbose", | |
| applicability = "machine-applicable", | |
| code = "" | |
| )] | |
| pub comma: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected `:`, found `=`")] | |
| pub(crate) struct EqFieldInit { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "replace equals symbol with a colon", | |
| applicability = "machine-applicable", | |
| code = ":", | |
| style = "verbose" | |
| )] | |
| pub eq: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected token: `...`")] | |
| pub(crate) struct DotDotDot { | |
| #[primary_span] | |
| #[suggestion( | |
| "use `..` for an exclusive range", | |
| applicability = "maybe-incorrect", | |
| code = "..", | |
| style = "verbose" | |
| )] | |
| #[suggestion( | |
| "or `..=` for an inclusive range", | |
| applicability = "maybe-incorrect", | |
| code = "..=", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected token: `<-`")] | |
| pub(crate) struct LeftArrowOperator { | |
| #[primary_span] | |
| #[suggestion( | |
| "if you meant to write a comparison against a negative value, add a space in between `<` and `-`", | |
| applicability = "maybe-incorrect", | |
| code = "< -", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected pattern, found `let`")] | |
| pub(crate) struct RemoveLet { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "remove the unnecessary `let` keyword", | |
| applicability = "machine-applicable", | |
| code = "", | |
| style = "verbose" | |
| )] | |
| pub suggestion: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected `==`")] | |
| pub(crate) struct UseEqInstead { | |
| #[primary_span] | |
| #[suggestion( | |
| "try using `=` instead", | |
| style = "verbose", | |
| applicability = "machine-applicable", | |
| code = "=" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected { \"`{}`\" }, found `;`")] | |
| pub(crate) struct UseEmptyBlockNotSemi { | |
| #[primary_span] | |
| #[suggestion( | |
| r#"try using { "`{}`" } instead"#, | |
| style = "hidden", | |
| applicability = "machine-applicable", | |
| code = "{{}}" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`<` is interpreted as a start of generic arguments for `{$type}`, not a comparison")] | |
| pub(crate) struct ComparisonInterpretedAsGeneric { | |
| #[primary_span] | |
| #[label("not interpreted as comparison")] | |
| pub comparison: Span, | |
| pub r#type: String, | |
| #[label("interpreted as generic arguments")] | |
| pub args: Span, | |
| #[subdiagnostic] | |
| pub suggestion: ComparisonInterpretedAsGenericSugg, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion("try comparing the cast value", applicability = "machine-applicable")] | |
| pub(crate) struct ComparisonInterpretedAsGenericSugg { | |
| #[suggestion_part(code = "(")] | |
| pub left: Span, | |
| #[suggestion_part(code = ")")] | |
| pub right: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`<<` is interpreted as a start of generic arguments for `{$type}`, not a shift")] | |
| pub(crate) struct ShiftInterpretedAsGeneric { | |
| #[primary_span] | |
| #[label("not interpreted as shift")] | |
| pub shift: Span, | |
| pub r#type: String, | |
| #[label("interpreted as generic arguments")] | |
| pub args: Span, | |
| #[subdiagnostic] | |
| pub suggestion: ShiftInterpretedAsGenericSugg, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion("try shifting the cast value", applicability = "machine-applicable")] | |
| pub(crate) struct ShiftInterpretedAsGenericSugg { | |
| #[suggestion_part(code = "(")] | |
| pub left: Span, | |
| #[suggestion_part(code = ")")] | |
| pub right: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected expression, found `{$token}`")] | |
| pub(crate) struct FoundExprWouldBeStmt { | |
| #[primary_span] | |
| #[label("expected expression")] | |
| pub span: Span, | |
| pub token: Cow<'static, str>, | |
| #[subdiagnostic] | |
| pub suggestion: ExprParenthesesNeeded, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "parentheses are required to parse this as an expression", | |
| applicability = "machine-applicable" | |
| )] | |
| pub(crate) struct ExprParenthesesNeeded { | |
| #[suggestion_part(code = "(")] | |
| left: Span, | |
| #[suggestion_part(code = ")")] | |
| right: Span, | |
| } | |
| impl ExprParenthesesNeeded { | |
| pub(crate) fn surrounding(s: Span) -> Self { | |
| ExprParenthesesNeeded { left: s.shrink_to_lo(), right: s.shrink_to_hi() } | |
| } | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("extra characters after frontmatter close are not allowed")] | |
| pub(crate) struct FrontmatterExtraCharactersAfterClose { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("invalid infostring for frontmatter")] | |
| #[note("frontmatter infostrings must be a single identifier immediately following the opening")] | |
| pub(crate) struct FrontmatterInvalidInfostring { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("invalid preceding whitespace for frontmatter opening")] | |
| pub(crate) struct FrontmatterInvalidOpeningPrecedingWhitespace { | |
| #[primary_span] | |
| pub span: Span, | |
| #[note("frontmatter opening should not be preceded by whitespace")] | |
| pub note_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unclosed frontmatter")] | |
| pub(crate) struct FrontmatterUnclosed { | |
| #[primary_span] | |
| pub span: Span, | |
| #[note("frontmatter opening here was not closed")] | |
| pub note_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("invalid preceding whitespace for frontmatter close")] | |
| pub(crate) struct FrontmatterInvalidClosingPrecedingWhitespace { | |
| #[primary_span] | |
| pub span: Span, | |
| #[note("frontmatter close should not be preceded by whitespace")] | |
| pub note_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("frontmatter close does not match the opening")] | |
| pub(crate) struct FrontmatterLengthMismatch { | |
| #[primary_span] | |
| pub span: Span, | |
| #[label("the opening here has {$len_opening} dashes...")] | |
| pub opening: Span, | |
| #[label("...while the close has {$len_close} dashes")] | |
| pub close: Span, | |
| pub len_opening: usize, | |
| pub len_close: usize, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "too many `-` symbols: frontmatter openings may be delimited by up to 255 `-` symbols, but found {$len_opening}" | |
| )] | |
| pub(crate) struct FrontmatterTooManyDashes { | |
| pub len_opening: usize, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("bare CR not allowed in frontmatter")] | |
| pub(crate) struct BareCrFrontmatter { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("leading `+` is not supported")] | |
| pub(crate) struct LeadingPlusNotSupported { | |
| #[primary_span] | |
| #[label("unexpected `+`")] | |
| pub span: Span, | |
| #[suggestion( | |
| "try removing the `+`", | |
| style = "verbose", | |
| code = "", | |
| applicability = "machine-applicable" | |
| )] | |
| pub remove_plus: Option<Span>, | |
| #[subdiagnostic] | |
| pub add_parentheses: Option<ExprParenthesesNeeded>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("invalid `struct` delimiters or `fn` call arguments")] | |
| pub(crate) struct ParenthesesWithStructFields { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub braces_for_struct: BracesForStructLiteral, | |
| #[subdiagnostic] | |
| pub no_fields_for_fn: NoFieldsForFnCall, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "if `{$type}` is a struct, use braces as delimiters", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub(crate) struct BracesForStructLiteral { | |
| pub r#type: String, | |
| #[suggestion_part(code = " {{ ")] | |
| pub first: Span, | |
| #[suggestion_part(code = " }}")] | |
| pub second: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "if `{$type}` is a function, use the arguments directly", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub(crate) struct NoFieldsForFnCall { | |
| pub r#type: String, | |
| #[suggestion_part(code = "")] | |
| pub fields: Vec<Span>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "parentheses are required around this expression to avoid confusion with a labeled break expression" | |
| )] | |
| pub(crate) struct LabeledLoopInBreak { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sub: WrapInParentheses, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum WrapInParentheses { | |
| #[multipart_suggestion( | |
| "wrap the expression in parentheses", | |
| applicability = "machine-applicable" | |
| )] | |
| Expression { | |
| #[suggestion_part(code = "(")] | |
| left: Span, | |
| #[suggestion_part(code = ")")] | |
| right: Span, | |
| }, | |
| #[multipart_suggestion( | |
| "use parentheses instead of braces for this macro", | |
| applicability = "machine-applicable" | |
| )] | |
| MacroArgs { | |
| #[suggestion_part(code = "(")] | |
| left: Span, | |
| #[suggestion_part(code = ")")] | |
| right: Span, | |
| }, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("this is a block expression, not an array")] | |
| pub(crate) struct ArrayBracketsInsteadOfBraces { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sub: ArrayBracketsInsteadOfBracesSugg, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "to make an array, use square brackets instead of curly braces", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub(crate) struct ArrayBracketsInsteadOfBracesSugg { | |
| #[suggestion_part(code = "[")] | |
| pub left: Span, | |
| #[suggestion_part(code = "]")] | |
| pub right: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`match` arm body without braces")] | |
| pub(crate) struct MatchArmBodyWithoutBraces { | |
| #[primary_span] | |
| #[label( | |
| "{$num_statements -> | |
| [one] this statement is not surrounded by a body | |
| *[other] these statements are not surrounded by a body | |
| }" | |
| )] | |
| pub statements: Span, | |
| #[label("while parsing the `match` arm starting here")] | |
| pub arrow: Span, | |
| pub num_statements: usize, | |
| #[subdiagnostic] | |
| pub sub: MatchArmBodyWithoutBracesSugg, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected `=` after inclusive range")] | |
| #[note("inclusive ranges end with a single equals sign (`..=`)")] | |
| pub(crate) struct InclusiveRangeExtraEquals { | |
| #[primary_span] | |
| #[suggestion( | |
| "use `..=` instead", | |
| style = "verbose", | |
| code = "..=", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected `>` after inclusive range")] | |
| pub(crate) struct InclusiveRangeMatchArrow { | |
| #[primary_span] | |
| pub arrow: Span, | |
| #[label("this is parsed as an inclusive range `..=`")] | |
| #[suggestion( | |
| "add a space between the pattern and `=>`", | |
| style = "verbose", | |
| code = ".. =", | |
| applicability = "machine-applicable" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("inclusive range with no end", code = E0586)] | |
| #[note("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)")] | |
| pub(crate) struct InclusiveRangeNoEnd { | |
| #[primary_span] | |
| #[suggestion( | |
| "use `..` instead", | |
| code = "..", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum MatchArmBodyWithoutBracesSugg { | |
| #[multipart_suggestion( | |
| "surround the {$num_statements -> | |
| [one] statement | |
| *[other] statements | |
| } with a body", | |
| applicability = "machine-applicable" | |
| )] | |
| AddBraces { | |
| #[suggestion_part(code = "{{ ")] | |
| left: Span, | |
| #[suggestion_part(code = " }}")] | |
| right: Span, | |
| num_statements: usize, | |
| }, | |
| #[suggestion( | |
| "replace `;` with `,` to end a `match` arm expression", | |
| code = ",", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| UseComma { | |
| #[primary_span] | |
| semicolon: Span, | |
| }, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("struct literals are not allowed here")] | |
| pub(crate) struct StructLiteralNotAllowedHere { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sub: StructLiteralNotAllowedHereSugg, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "surround the struct literal with parentheses", | |
| applicability = "machine-applicable" | |
| )] | |
| pub(crate) struct StructLiteralNotAllowedHereSugg { | |
| #[suggestion_part(code = "(")] | |
| pub left: Span, | |
| #[suggestion_part(code = ")")] | |
| pub right: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("suffixes on a tuple index are invalid")] | |
| pub(crate) struct InvalidLiteralSuffixOnTupleIndex { | |
| #[primary_span] | |
| #[label("invalid suffix `{$suffix}`")] | |
| pub span: Span, | |
| pub suffix: Symbol, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("non-string ABI literal")] | |
| pub(crate) struct NonStringAbiLiteral { | |
| #[primary_span] | |
| #[suggestion( | |
| "specify the ABI with a string literal", | |
| code = "\"C\"", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("mismatched closing delimiter: `{$delimiter}`")] | |
| pub(crate) struct MismatchedClosingDelimiter { | |
| #[primary_span] | |
| pub spans: Vec<Span>, | |
| pub delimiter: String, | |
| #[label("mismatched closing delimiter")] | |
| pub unmatched: Span, | |
| #[label("closing delimiter possibly meant for this")] | |
| pub opening_candidate: Option<Span>, | |
| #[label("unclosed delimiter")] | |
| pub unclosed: Option<Span>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("incorrect visibility restriction", code = E0704)] | |
| #[help( | |
| "some possible visibility restrictions are: | |
| `pub(crate)`: visible only on the current crate | |
| `pub(super)`: visible only in the current module's parent | |
| `pub(in path::to::module)`: visible only on the specified path" | |
| )] | |
| pub(crate) struct IncorrectVisibilityRestriction { | |
| #[primary_span] | |
| #[suggestion( | |
| "make this visible only to module `{$inner_str}` with `in`", | |
| code = "in {inner_str}", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| pub inner_str: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("incorrect `impl` restriction")] | |
| #[help( | |
| "some possible `impl` restrictions are: | |
| `impl(crate)`: can only be implemented in the current crate | |
| `impl(super)`: can only be implemented in the parent module | |
| `impl(self)`: can only be implemented in current module | |
| `impl(in path::to::module)`: can only be implemented in the specified path" | |
| )] | |
| pub(crate) struct IncorrectImplRestriction { | |
| #[primary_span] | |
| #[suggestion( | |
| "help: use `in` to restrict implementations to the path `{$inner_str}`", | |
| code = "in {inner_str}", | |
| applicability = "machine-applicable" | |
| )] | |
| pub span: Span, | |
| pub inner_str: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("incorrect `mut` restriction")] | |
| #[help( | |
| "some possible `mut` restrictions are: | |
| `mut(crate)`: can only be mutated in the current crate | |
| `mut(super)`: can only be mutated in the parent module | |
| `mut(self)`: can only be mutated in current module | |
| `mut(in path::to::module)`: can only be mutated in the specified path" | |
| )] | |
| pub(crate) struct IncorrectMutRestriction { | |
| #[primary_span] | |
| #[suggestion( | |
| "help: use `in` to restrict mutations to the path `{$inner_str}`", | |
| code = "in {inner_str}", | |
| applicability = "machine-applicable" | |
| )] | |
| pub span: Span, | |
| pub inner_str: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("<assignment> ... else {\"{\"} ... {\"}\"} is not allowed")] | |
| pub(crate) struct AssignmentElseNotAllowed { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected statement after outer attribute")] | |
| pub(crate) struct ExpectedStatementAfterOuterAttr { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("attribute without where predicates")] | |
| pub(crate) struct AttrWithoutWherePredicates { | |
| #[primary_span] | |
| #[label("attributes are only permitted when preceding predicates")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("found a documentation comment that doesn't document anything", code = E0585)] | |
| #[help("doc comments must come before what they document, if a comment was intended use `//`")] | |
| pub(crate) struct DocCommentDoesNotDocumentAnything { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "missing comma here", | |
| code = ",", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub missing_comma: Option<Span>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`const` and `let` are mutually exclusive")] | |
| pub(crate) struct ConstLetMutuallyExclusive { | |
| #[primary_span] | |
| #[suggestion( | |
| "remove `let`", | |
| code = "const", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("a `{$operator}` expression cannot be directly assigned in `let...else`")] | |
| pub(crate) struct InvalidExpressionInLetElse { | |
| #[primary_span] | |
| pub span: Span, | |
| pub operator: &'static str, | |
| #[subdiagnostic] | |
| pub sugg: WrapInParentheses, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("right curly brace `{\"}\"}` before `else` in a `let...else` statement not allowed")] | |
| pub(crate) struct InvalidCurlyInLetElse { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sugg: WrapInParentheses, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("can't reassign to an uninitialized variable")] | |
| #[help("if you meant to overwrite, remove the `let` binding")] | |
| pub(crate) struct CompoundAssignmentExpressionInLet { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "initialize the variable", | |
| style = "verbose", | |
| code = "", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub suggestion: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("suffixed literals are not allowed in attributes")] | |
| #[help( | |
| "instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)" | |
| )] | |
| pub(crate) struct SuffixedLiteralInAttribute { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected unsuffixed literal, found {$descr}")] | |
| pub(crate) struct InvalidMetaItem { | |
| #[primary_span] | |
| pub span: Span, | |
| pub descr: String, | |
| #[subdiagnostic] | |
| pub quote_ident_sugg: Option<InvalidMetaItemQuoteIdentSugg>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "surround the identifier with quotation marks to make it into a string literal", | |
| applicability = "machine-applicable" | |
| )] | |
| pub(crate) struct InvalidMetaItemQuoteIdentSugg { | |
| #[suggestion_part(code = "\"")] | |
| pub before: Span, | |
| #[suggestion_part(code = "\"")] | |
| pub after: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[suggestion( | |
| "escape `{$ident_name}` to use it as an identifier", | |
| style = "verbose", | |
| applicability = "maybe-incorrect", | |
| code = "r#" | |
| )] | |
| pub(crate) struct SuggEscapeIdentifier { | |
| #[primary_span] | |
| pub span: Span, | |
| pub ident_name: String, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[suggestion( | |
| "remove this comma", | |
| applicability = "machine-applicable", | |
| code = "", | |
| style = "verbose" | |
| )] | |
| pub(crate) struct SuggRemoveComma { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[suggestion( | |
| "you might have meant to introduce a new binding", | |
| style = "verbose", | |
| applicability = "maybe-incorrect", | |
| code = "let " | |
| )] | |
| pub(crate) struct SuggAddMissingLetStmt { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum ExpectedIdentifierFound { | |
| #[label("expected identifier, found reserved identifier")] | |
| ReservedIdentifier(#[primary_span] Span), | |
| #[label("expected identifier, found keyword")] | |
| Keyword(#[primary_span] Span), | |
| #[label("expected identifier, found reserved keyword")] | |
| ReservedKeyword(#[primary_span] Span), | |
| #[label("expected identifier, found doc comment")] | |
| DocComment(#[primary_span] Span), | |
| #[label("expected identifier, found metavariable")] | |
| MetaVar(#[primary_span] Span), | |
| #[label("expected identifier")] | |
| Other(#[primary_span] Span), | |
| } | |
| impl ExpectedIdentifierFound { | |
| pub(crate) fn new(token_descr: Option<TokenDescription>, span: Span) -> Self { | |
| (match token_descr { | |
| Some(TokenDescription::ReservedIdentifier) => { | |
| ExpectedIdentifierFound::ReservedIdentifier | |
| } | |
| Some(TokenDescription::Keyword) => ExpectedIdentifierFound::Keyword, | |
| Some(TokenDescription::ReservedKeyword) => ExpectedIdentifierFound::ReservedKeyword, | |
| Some(TokenDescription::DocComment) => ExpectedIdentifierFound::DocComment, | |
| Some(TokenDescription::MetaVar(_)) => ExpectedIdentifierFound::MetaVar, | |
| None => ExpectedIdentifierFound::Other, | |
| })(span) | |
| } | |
| } | |
| pub(crate) struct ExpectedIdentifier { | |
| pub span: Span, | |
| pub token: Token, | |
| pub suggest_raw: Option<SuggEscapeIdentifier>, | |
| pub suggest_remove_comma: Option<SuggRemoveComma>, | |
| pub help_cannot_start_number: Option<HelpIdentifierStartsWithNumber>, | |
| } | |
| impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedIdentifier { | |
| #[track_caller] | |
| fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { | |
| let token_descr = TokenDescription::from_token(&self.token); | |
| let mut add_token = true; | |
| let mut diag = Diag::new( | |
| dcx, | |
| level, | |
| match token_descr { | |
| Some(TokenDescription::ReservedIdentifier) => { | |
| msg!("expected identifier, found reserved identifier `{$token}`") | |
| } | |
| Some(TokenDescription::Keyword) => { | |
| msg!("expected identifier, found keyword `{$token}`") | |
| } | |
| Some(TokenDescription::ReservedKeyword) => { | |
| msg!("expected identifier, found reserved keyword `{$token}`") | |
| } | |
| Some(TokenDescription::DocComment) => { | |
| msg!("expected identifier, found doc comment `{$token}`") | |
| } | |
| Some(TokenDescription::MetaVar(_)) => { | |
| add_token = false; | |
| msg!("expected identifier, found metavariable") | |
| } | |
| None => msg!("expected identifier, found `{$token}`"), | |
| }, | |
| ); | |
| diag.span(self.span); | |
| if add_token { | |
| diag.arg("token", pprust::token_to_string(&self.token)); | |
| } | |
| if let Some(sugg) = self.suggest_raw { | |
| sugg.add_to_diag(&mut diag); | |
| } | |
| ExpectedIdentifierFound::new(token_descr, self.span).add_to_diag(&mut diag); | |
| if let Some(sugg) = self.suggest_remove_comma { | |
| sugg.add_to_diag(&mut diag); | |
| } | |
| if let Some(help) = self.help_cannot_start_number { | |
| help.add_to_diag(&mut diag); | |
| } | |
| diag | |
| } | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[help("identifiers cannot start with a number")] | |
| pub(crate) struct HelpIdentifierStartsWithNumber { | |
| #[primary_span] | |
| pub num_span: Span, | |
| } | |
| pub(crate) struct ExpectedSemi { | |
| pub span: Span, | |
| pub token: Token, | |
| pub unexpected_token_label: Option<Span>, | |
| pub sugg: ExpectedSemiSugg, | |
| } | |
| impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedSemi { | |
| #[track_caller] | |
| fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { | |
| let token_descr = TokenDescription::from_token(&self.token); | |
| let mut add_token = true; | |
| let mut diag = Diag::new( | |
| dcx, | |
| level, | |
| match token_descr { | |
| Some(TokenDescription::ReservedIdentifier) => { | |
| msg!("expected `;`, found reserved identifier `{$token}`") | |
| } | |
| Some(TokenDescription::Keyword) => { | |
| msg!("expected `;`, found keyword `{$token}`") | |
| } | |
| Some(TokenDescription::ReservedKeyword) => { | |
| msg!("expected `;`, found reserved keyword `{$token}`") | |
| } | |
| Some(TokenDescription::DocComment) => { | |
| msg!("expected `;`, found doc comment `{$token}`") | |
| } | |
| Some(TokenDescription::MetaVar(_)) => { | |
| add_token = false; | |
| msg!("expected `;`, found metavariable") | |
| } | |
| None => msg!("expected `;`, found `{$token}`"), | |
| }, | |
| ); | |
| diag.span(self.span); | |
| if add_token { | |
| diag.arg("token", pprust::token_to_string(&self.token)); | |
| } | |
| if let Some(unexpected_token_label) = self.unexpected_token_label { | |
| diag.span_label(unexpected_token_label, msg!("unexpected token")); | |
| } | |
| self.sugg.add_to_diag(&mut diag); | |
| diag | |
| } | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum ExpectedSemiSugg { | |
| #[suggestion( | |
| "change this to `;`", | |
| code = ";", | |
| applicability = "machine-applicable", | |
| style = "short" | |
| )] | |
| ChangeToSemi(#[primary_span] Span), | |
| #[suggestion("add `;` here", code = ";", applicability = "machine-applicable", style = "short")] | |
| AddSemi(#[primary_span] Span), | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("struct literal body without path")] | |
| pub(crate) struct StructLiteralBodyWithoutPath { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sugg: StructLiteralBodyWithoutPathSugg, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "you might have forgotten to add the struct literal inside the block", | |
| applicability = "has-placeholders" | |
| )] | |
| pub(crate) struct StructLiteralBodyWithoutPathSugg { | |
| #[suggestion_part(code = "{{ SomeStruct ")] | |
| pub before: Span, | |
| #[suggestion_part(code = " }}")] | |
| pub after: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "{$num_extra_brackets -> | |
| [one] unmatched angle bracket | |
| *[other] unmatched angle brackets | |
| }" | |
| )] | |
| pub(crate) struct UnmatchedAngleBrackets { | |
| #[primary_span] | |
| #[suggestion( | |
| "{$num_extra_brackets -> | |
| [one] remove extra angle bracket | |
| *[other] remove extra angle brackets | |
| }", | |
| code = "", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| pub num_extra_brackets: usize, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("generic parameters without surrounding angle brackets")] | |
| pub(crate) struct GenericParamsWithoutAngleBrackets { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sugg: GenericParamsWithoutAngleBracketsSugg, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "surround the type parameters with angle brackets", | |
| applicability = "machine-applicable" | |
| )] | |
| pub(crate) struct GenericParamsWithoutAngleBracketsSugg { | |
| #[suggestion_part(code = "<")] | |
| pub left: Span, | |
| #[suggestion_part(code = ">")] | |
| pub right: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("comparison operators cannot be chained")] | |
| pub(crate) struct ComparisonOperatorsCannotBeChained { | |
| #[primary_span] | |
| pub span: Vec<Span>, | |
| #[suggestion( | |
| "use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments", | |
| style = "verbose", | |
| code = "::", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub suggest_turbofish: Option<Span>, | |
| #[help("use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments")] | |
| #[help("or use `(...)` if you meant to specify fn arguments")] | |
| pub help_turbofish: bool, | |
| #[subdiagnostic] | |
| pub chaining_sugg: Option<ComparisonOperatorsCannotBeChainedSugg>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum ComparisonOperatorsCannotBeChainedSugg { | |
| #[suggestion( | |
| "split the comparison into two", | |
| style = "verbose", | |
| code = " && {middle_term}", | |
| applicability = "maybe-incorrect" | |
| )] | |
| SplitComparison { | |
| #[primary_span] | |
| span: Span, | |
| middle_term: String, | |
| }, | |
| #[multipart_suggestion("parenthesize the comparison", applicability = "maybe-incorrect")] | |
| Parenthesize { | |
| #[suggestion_part(code = "(")] | |
| left: Span, | |
| #[suggestion_part(code = ")")] | |
| right: Span, | |
| }, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("invalid `?` in type")] | |
| pub(crate) struct QuestionMarkInType { | |
| #[primary_span] | |
| #[label("`?` is only allowed on expressions, not types")] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sugg: QuestionMarkInTypeSugg, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "if you meant to express that the type might not contain a value, use the `Option` wrapper type", | |
| applicability = "machine-applicable" | |
| )] | |
| pub(crate) struct QuestionMarkInTypeSugg { | |
| #[suggestion_part(code = "Option<")] | |
| pub left: Span, | |
| #[suggestion_part(code = ">")] | |
| pub right: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected parentheses surrounding `for` loop head")] | |
| pub(crate) struct ParenthesesInForHead { | |
| #[primary_span] | |
| pub span: Vec<Span>, | |
| #[subdiagnostic] | |
| pub sugg: ParenthesesInForHeadSugg, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion("remove parentheses in `for` loop", applicability = "machine-applicable")] | |
| pub(crate) struct ParenthesesInForHeadSugg { | |
| #[suggestion_part(code = " ")] | |
| pub left: Span, | |
| #[suggestion_part(code = " ")] | |
| pub right: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected parentheses surrounding `match` arm pattern")] | |
| pub(crate) struct ParenthesesInMatchPat { | |
| #[primary_span] | |
| pub span: Vec<Span>, | |
| #[subdiagnostic] | |
| pub sugg: ParenthesesInMatchPatSugg, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "remove parentheses surrounding the pattern", | |
| applicability = "machine-applicable" | |
| )] | |
| pub(crate) struct ParenthesesInMatchPatSugg { | |
| #[suggestion_part(code = "")] | |
| pub left: Span, | |
| #[suggestion_part(code = "")] | |
| pub right: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("documentation comments cannot be applied to a function parameter's type")] | |
| pub(crate) struct DocCommentOnParamType { | |
| #[primary_span] | |
| #[label("doc comments are not allowed here")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("attributes cannot be applied to a function parameter's type")] | |
| pub(crate) struct AttributeOnParamType { | |
| #[primary_span] | |
| #[label("attributes are not allowed here")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("attributes cannot be applied to types")] | |
| pub(crate) struct AttributeOnType { | |
| #[primary_span] | |
| #[label("attributes are not allowed here")] | |
| pub span: Span, | |
| #[suggestion( | |
| "remove attribute from here", | |
| code = "", | |
| applicability = "machine-applicable", | |
| style = "tool-only" | |
| )] | |
| pub fix_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("attributes cannot be applied to generic arguments")] | |
| pub(crate) struct AttributeOnGenericArg { | |
| #[primary_span] | |
| #[label("attributes are not allowed here")] | |
| pub span: Span, | |
| #[suggestion( | |
| "remove attribute from here", | |
| code = "", | |
| applicability = "machine-applicable", | |
| style = "tool-only" | |
| )] | |
| pub fix_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("attributes cannot be applied here")] | |
| pub(crate) struct AttributeOnEmptyType { | |
| #[primary_span] | |
| #[label("attributes are not allowed here")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("patterns aren't allowed in {$target}", code = E0642)] | |
| pub(crate) struct PatternMethodParamWithoutBody { | |
| #[primary_span] | |
| #[suggestion( | |
| "give this argument a name or use an underscore to ignore it", | |
| code = "_", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| pub target: &'static str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected `self` parameter in function")] | |
| pub(crate) struct SelfParamNotFirst { | |
| #[primary_span] | |
| #[label("must be the first parameter of an associated function")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expressions must be enclosed in braces to be used as const generic arguments")] | |
| pub(crate) struct ConstGenericWithoutBraces { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sugg: ConstGenericWithoutBracesSugg, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "enclose the `const` expression in braces", | |
| applicability = "machine-applicable" | |
| )] | |
| pub(crate) struct ConstGenericWithoutBracesSugg { | |
| #[suggestion_part(code = "{{ ")] | |
| pub left: Span, | |
| #[suggestion_part(code = " }}")] | |
| pub right: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected `const` parameter declaration")] | |
| pub(crate) struct UnexpectedConstParamDeclaration { | |
| #[primary_span] | |
| #[label("expected a `const` expression, not a parameter declaration")] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sugg: Option<UnexpectedConstParamDeclarationSugg>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum UnexpectedConstParamDeclarationSugg { | |
| #[multipart_suggestion( | |
| "`const` parameters must be declared for the `impl`", | |
| applicability = "machine-applicable" | |
| )] | |
| AddParam { | |
| #[suggestion_part(code = "<{snippet}>")] | |
| impl_generics: Span, | |
| #[suggestion_part(code = "{ident}")] | |
| incorrect_decl: Span, | |
| snippet: String, | |
| ident: String, | |
| }, | |
| #[multipart_suggestion( | |
| "`const` parameters must be declared for the `impl`", | |
| applicability = "machine-applicable" | |
| )] | |
| AppendParam { | |
| #[suggestion_part(code = ", {snippet}")] | |
| impl_generics_end: Span, | |
| #[suggestion_part(code = "{ident}")] | |
| incorrect_decl: Span, | |
| snippet: String, | |
| ident: String, | |
| }, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected lifetime, type, or constant, found keyword `const`")] | |
| pub(crate) struct UnexpectedConstInGenericParam { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "the `const` keyword is only needed in the definition of the type", | |
| style = "verbose", | |
| code = "", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub to_remove: Option<Span>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("the order of `move` and `async` is incorrect")] | |
| pub(crate) struct AsyncMoveOrderIncorrect { | |
| #[primary_span] | |
| #[suggestion( | |
| "try switching the order", | |
| style = "verbose", | |
| code = "async move", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("the order of `use` and `async` is incorrect")] | |
| pub(crate) struct AsyncUseOrderIncorrect { | |
| #[primary_span] | |
| #[suggestion( | |
| "try switching the order", | |
| style = "verbose", | |
| code = "async use", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected `:` followed by trait or lifetime")] | |
| pub(crate) struct DoubleColonInBound { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "use single colon", | |
| code = ": ", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub between: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("function pointer types may not have generic parameters")] | |
| pub(crate) struct FnPtrWithGenerics { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sugg: Option<FnPtrWithGenericsSugg>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "place the return type after the function parameters", | |
| style = "verbose", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub(crate) struct MisplacedReturnType { | |
| #[suggestion_part(code = " {snippet}")] | |
| pub fn_params_end: Span, | |
| pub snippet: String, | |
| #[suggestion_part(code = "")] | |
| pub ret_ty_span: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "consider moving the lifetime {$arity -> | |
| [one] parameter | |
| *[other] parameters | |
| } to {$for_param_list_exists -> | |
| [true] the | |
| *[false] a | |
| } `for` parameter list", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub(crate) struct FnPtrWithGenericsSugg { | |
| #[suggestion_part(code = "{snippet}")] | |
| pub left: Span, | |
| pub snippet: String, | |
| #[suggestion_part(code = "")] | |
| pub right: Span, | |
| pub arity: usize, | |
| pub for_param_list_exists: bool, | |
| } | |
| pub(crate) struct FnTraitMissingParen { | |
| pub span: Span, | |
| } | |
| impl Subdiagnostic for FnTraitMissingParen { | |
| fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) { | |
| diag.span_label(self.span, msg!("`Fn` bounds require arguments in parentheses")); | |
| diag.span_suggestion_short( | |
| self.span.shrink_to_hi(), | |
| msg!("try adding parentheses"), | |
| "()", | |
| Applicability::MachineApplicable, | |
| ); | |
| } | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected `if` in the condition expression")] | |
| pub(crate) struct UnexpectedIfWithIf( | |
| #[primary_span] | |
| #[suggestion( | |
| "remove the `if`", | |
| applicability = "machine-applicable", | |
| code = " ", | |
| style = "verbose" | |
| )] | |
| pub Span, | |
| ); | |
| #[derive(Diagnostic)] | |
| #[diag("you might have meant to write `impl` instead of `fn`")] | |
| pub(crate) struct FnTypoWithImpl { | |
| #[primary_span] | |
| #[suggestion( | |
| "replace `fn` with `impl` here", | |
| applicability = "maybe-incorrect", | |
| code = "impl", | |
| style = "verbose" | |
| )] | |
| pub fn_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected identifier, found keyword `fn`")] | |
| pub(crate) struct ExpectedFnPathFoundFnKeyword { | |
| #[primary_span] | |
| #[suggestion( | |
| "use `Fn` to refer to the trait", | |
| applicability = "machine-applicable", | |
| code = "Fn", | |
| style = "verbose" | |
| )] | |
| pub fn_token_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`Trait(...)` syntax does not support c_variadic parameters")] | |
| pub(crate) struct PathFoundCVariadicParams { | |
| #[primary_span] | |
| #[suggestion("remove the `...`", applicability = "machine-applicable", code = "")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`Trait(...)` syntax does not support attributes in parameters")] | |
| pub(crate) struct PathFoundAttributeInParams { | |
| #[primary_span] | |
| #[suggestion("remove the attributes", applicability = "machine-applicable", code = "")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("path separator must be a double colon")] | |
| pub(crate) struct PathSingleColon { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "use a double colon instead", | |
| applicability = "machine-applicable", | |
| code = ":", | |
| style = "verbose" | |
| )] | |
| pub suggestion: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("path separator must be a double colon")] | |
| pub(crate) struct PathTripleColon { | |
| #[primary_span] | |
| #[suggestion( | |
| "use a double colon instead", | |
| applicability = "maybe-incorrect", | |
| code = "", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("statements are terminated with a semicolon")] | |
| pub(crate) struct ColonAsSemi { | |
| #[primary_span] | |
| #[suggestion( | |
| "use a semicolon instead", | |
| applicability = "machine-applicable", | |
| code = ";", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("where clauses are not allowed before tuple struct bodies")] | |
| pub(crate) struct WhereClauseBeforeTupleStructBody { | |
| #[primary_span] | |
| #[label("unexpected where clause")] | |
| pub span: Span, | |
| #[label("while parsing this tuple struct")] | |
| pub name: Span, | |
| #[label("the struct body")] | |
| pub body: Span, | |
| #[subdiagnostic] | |
| pub sugg: Option<WhereClauseBeforeTupleStructBodySugg>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "move the body before the where clause", | |
| applicability = "machine-applicable" | |
| )] | |
| pub(crate) struct WhereClauseBeforeTupleStructBodySugg { | |
| #[suggestion_part(code = "{snippet}")] | |
| pub left: Span, | |
| pub snippet: String, | |
| #[suggestion_part(code = "")] | |
| pub right: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`async fn` is not permitted in Rust 2015", code = E0670)] | |
| pub(crate) struct AsyncFnIn2015 { | |
| #[primary_span] | |
| #[label("to use `async fn`, switch to Rust 2018 or later")] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub help: HelpUseLatestEdition, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[label("`async` blocks are only allowed in Rust 2018 or later")] | |
| pub(crate) struct AsyncBlockIn2015 { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`async move` blocks are only allowed in Rust 2018 or later")] | |
| pub(crate) struct AsyncMoveBlockIn2015 { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`async use` blocks are only allowed in Rust 2018 or later")] | |
| pub(crate) struct AsyncUseBlockIn2015 { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`async` trait bounds are only allowed in Rust 2018 or later")] | |
| pub(crate) struct AsyncBoundModifierIn2015 { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub help: HelpUseLatestEdition, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("let chains are only allowed in Rust 2024 or later")] | |
| pub(crate) struct LetChainPre2024 { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("cannot pass `self` by raw pointer")] | |
| pub(crate) struct SelfArgumentPointer { | |
| #[primary_span] | |
| #[label("cannot pass `self` by raw pointer")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected token: {$actual}")] | |
| pub(crate) struct UnexpectedTokenAfterDot { | |
| #[primary_span] | |
| pub span: Span, | |
| pub actual: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("visibility `{$vis}` is not followed by an item")] | |
| #[help("you likely meant to define an item, e.g., `{$vis} fn foo() {\"{}\"}`")] | |
| pub(crate) struct VisibilityNotFollowedByItem { | |
| #[primary_span] | |
| #[label("the visibility")] | |
| pub span: Span, | |
| pub vis: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`default` is not followed by an item")] | |
| #[note("only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`")] | |
| pub(crate) struct DefaultNotFollowedByItem { | |
| #[primary_span] | |
| #[label("the `default` qualifier")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`final` is not followed by an item")] | |
| #[note("only associated functions in traits may be prefixed by `final`")] | |
| pub(crate) struct FinalNotFollowedByItem { | |
| #[primary_span] | |
| #[label("the `final` qualifier")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| pub(crate) enum MissingKeywordForItemDefinition { | |
| #[diag("missing `enum` for enum definition")] | |
| Enum { | |
| #[primary_span] | |
| span: Span, | |
| #[suggestion( | |
| "add `enum` here to parse `{$ident}` as an enum", | |
| style = "verbose", | |
| applicability = "maybe-incorrect", | |
| code = "enum " | |
| )] | |
| insert_span: Span, | |
| ident: Ident, | |
| }, | |
| #[diag("missing `enum` or `struct` for enum or struct definition")] | |
| EnumOrStruct { | |
| #[primary_span] | |
| span: Span, | |
| }, | |
| #[diag("missing `struct` for struct definition")] | |
| Struct { | |
| #[primary_span] | |
| span: Span, | |
| #[suggestion( | |
| "add `struct` here to parse `{$ident}` as a struct", | |
| style = "verbose", | |
| applicability = "maybe-incorrect", | |
| code = "struct " | |
| )] | |
| insert_span: Span, | |
| ident: Ident, | |
| }, | |
| #[diag("missing `fn` for function definition")] | |
| Function { | |
| #[primary_span] | |
| span: Span, | |
| #[suggestion( | |
| "add `fn` here to parse `{$ident}` as a function", | |
| style = "verbose", | |
| applicability = "maybe-incorrect", | |
| code = "fn " | |
| )] | |
| insert_span: Span, | |
| ident: Ident, | |
| }, | |
| #[diag("missing `fn` for method definition")] | |
| Method { | |
| #[primary_span] | |
| span: Span, | |
| #[suggestion( | |
| "add `fn` here to parse `{$ident}` as a method", | |
| style = "verbose", | |
| applicability = "maybe-incorrect", | |
| code = "fn " | |
| )] | |
| insert_span: Span, | |
| ident: Ident, | |
| }, | |
| #[diag("missing `fn` or `struct` for function or struct definition")] | |
| Ambiguous { | |
| #[primary_span] | |
| span: Span, | |
| #[subdiagnostic] | |
| subdiag: Option<AmbiguousMissingKwForItemSub>, | |
| }, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum AmbiguousMissingKwForItemSub { | |
| #[suggestion( | |
| "if you meant to call a macro, try", | |
| applicability = "maybe-incorrect", | |
| code = "{snippet}!", | |
| style = "verbose" | |
| )] | |
| SuggestMacro { | |
| #[primary_span] | |
| span: Span, | |
| snippet: String, | |
| }, | |
| #[help( | |
| "if you meant to call a macro, remove the `pub` and add a trailing `!` after the identifier" | |
| )] | |
| HelpMacro, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("missing parameters for function definition")] | |
| pub(crate) struct MissingFnParams { | |
| #[primary_span] | |
| #[suggestion( | |
| "add a parameter list", | |
| code = "()", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("invalid path separator in function definition")] | |
| pub(crate) struct InvalidPathSepInFnDefinition { | |
| #[primary_span] | |
| #[suggestion( | |
| "remove invalid path separator", | |
| code = "", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("missing trait in a trait impl")] | |
| pub(crate) struct MissingTraitInTraitImpl { | |
| #[primary_span] | |
| #[suggestion( | |
| "add a trait here", | |
| code = " Trait ", | |
| applicability = "has-placeholders", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| #[suggestion( | |
| "for an inherent impl, drop this `for`", | |
| code = "", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| pub for_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("missing `for` in a trait impl")] | |
| pub(crate) struct MissingForInTraitImpl { | |
| #[primary_span] | |
| #[suggestion( | |
| "add `for` here", | |
| style = "verbose", | |
| code = " for ", | |
| applicability = "machine-applicable" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected a trait, found type")] | |
| pub(crate) struct ExpectedTraitInTraitImplFoundType { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected `impl` keyword")] | |
| pub(crate) struct ExtraImplKeywordInTraitImpl { | |
| #[primary_span] | |
| #[suggestion( | |
| "remove the extra `impl`", | |
| code = "", | |
| applicability = "maybe-incorrect", | |
| style = "short" | |
| )] | |
| pub extra_impl_kw: Span, | |
| #[note("this is parsed as an `impl Trait` type, but a trait is expected at this position")] | |
| pub impl_trait_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("bounds are not allowed on trait aliases")] | |
| pub(crate) struct BoundsNotAllowedOnTraitAliases { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("trait aliases cannot be `auto`")] | |
| pub(crate) struct TraitAliasCannotBeAuto { | |
| #[primary_span] | |
| #[label("trait aliases cannot be `auto`")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("trait aliases cannot be `unsafe`")] | |
| pub(crate) struct TraitAliasCannotBeUnsafe { | |
| #[primary_span] | |
| #[label("trait aliases cannot be `unsafe`")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("trait aliases cannot be `impl`-restricted")] | |
| pub(crate) struct TraitAliasCannotBeImplRestricted { | |
| #[primary_span] | |
| #[label("trait aliases cannot be `impl`-restricted")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("associated `static` items are not allowed")] | |
| pub(crate) struct AssociatedStaticItemNotAllowed { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("crate name using dashes are not valid in `extern crate` statements")] | |
| pub(crate) struct ExternCrateNameWithDashes { | |
| #[primary_span] | |
| #[label("dash-separated idents are not valid")] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sugg: ExternCrateNameWithDashesSugg, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "if the original crate name uses dashes you need to use underscores in the code", | |
| applicability = "machine-applicable" | |
| )] | |
| pub(crate) struct ExternCrateNameWithDashesSugg { | |
| #[suggestion_part(code = "_")] | |
| pub dashes: Vec<Span>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("extern items cannot be `const`")] | |
| #[note("for more information, visit https://doc.rust-lang.org/std/keyword.extern.html")] | |
| pub(crate) struct ExternItemCannotBeConst { | |
| #[primary_span] | |
| pub ident_span: Span, | |
| #[suggestion( | |
| "try using a static value", | |
| code = "static ", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub const_span: Option<Span>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("const globals cannot be mutable")] | |
| pub(crate) struct ConstGlobalCannotBeMutable { | |
| #[primary_span] | |
| #[label("cannot be mutable")] | |
| pub ident_span: Span, | |
| #[suggestion( | |
| "you might want to declare a static instead", | |
| code = "static", | |
| style = "verbose", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub const_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("missing type for `{$kind}` item")] | |
| pub(crate) struct MissingConstType { | |
| #[primary_span] | |
| #[suggestion( | |
| "provide a type for the item", | |
| code = "{colon} <type>", | |
| style = "verbose", | |
| applicability = "has-placeholders" | |
| )] | |
| pub span: Span, | |
| pub kind: &'static str, | |
| pub colon: &'static str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`enum` and `struct` are mutually exclusive")] | |
| pub(crate) struct EnumStructMutuallyExclusive { | |
| #[primary_span] | |
| #[suggestion( | |
| "replace `enum struct` with", | |
| code = "enum", | |
| style = "verbose", | |
| applicability = "machine-applicable" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| pub(crate) enum UnexpectedTokenAfterStructName { | |
| #[diag( | |
| "expected `where`, `{\"{\"}`, `(`, or `;` after struct name, found reserved identifier `{$token}`" | |
| )] | |
| ReservedIdentifier { | |
| #[primary_span] | |
| #[label("expected `where`, `{\"{\"}`, `(`, or `;` after struct name")] | |
| span: Span, | |
| token: Cow<'static, str>, | |
| }, | |
| #[diag("expected `where`, `{\"{\"}`, `(`, or `;` after struct name, found keyword `{$token}`")] | |
| Keyword { | |
| #[primary_span] | |
| #[label("expected `where`, `{\"{\"}`, `(`, or `;` after struct name")] | |
| span: Span, | |
| token: Cow<'static, str>, | |
| }, | |
| #[diag( | |
| "expected `where`, `{\"{\"}`, `(`, or `;` after struct name, found reserved keyword `{$token}`" | |
| )] | |
| ReservedKeyword { | |
| #[primary_span] | |
| #[label("expected `where`, `{\"{\"}`, `(`, or `;` after struct name")] | |
| span: Span, | |
| token: Cow<'static, str>, | |
| }, | |
| #[diag( | |
| "expected `where`, `{\"{\"}`, `(`, or `;` after struct name, found doc comment `{$token}`" | |
| )] | |
| DocComment { | |
| #[primary_span] | |
| #[label("expected `where`, `{\"{\"}`, `(`, or `;` after struct name")] | |
| span: Span, | |
| token: Cow<'static, str>, | |
| }, | |
| #[diag("expected `where`, `{\"{\"}`, `(`, or `;` after struct name, found metavar")] | |
| MetaVar { | |
| #[primary_span] | |
| #[label("expected `where`, `{\"{\"}`, `(`, or `;` after struct name")] | |
| span: Span, | |
| }, | |
| #[diag("expected `where`, `{\"{\"}`, `(`, or `;` after struct name, found `{$token}`")] | |
| Other { | |
| #[primary_span] | |
| #[label("expected `where`, `{\"{\"}`, `(`, or `;` after struct name")] | |
| span: Span, | |
| token: Cow<'static, str>, | |
| }, | |
| } | |
| impl UnexpectedTokenAfterStructName { | |
| pub(crate) fn new(span: Span, orig_token: Token) -> Self { | |
| let token = pprust::token_to_string(&orig_token); | |
| match TokenDescription::from_token(&orig_token) { | |
| Some(TokenDescription::ReservedIdentifier) => Self::ReservedIdentifier { span, token }, | |
| Some(TokenDescription::Keyword) => Self::Keyword { span, token }, | |
| Some(TokenDescription::ReservedKeyword) => Self::ReservedKeyword { span, token }, | |
| Some(TokenDescription::DocComment) => Self::DocComment { span, token }, | |
| Some(TokenDescription::MetaVar(_)) => Self::MetaVar { span }, | |
| None => Self::Other { span, token }, | |
| } | |
| } | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected keyword `Self` in generic parameters")] | |
| #[note("you cannot use `Self` as a generic parameter because it is reserved for associated items")] | |
| pub(crate) struct UnexpectedSelfInGenericParameters { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected default lifetime parameter")] | |
| pub(crate) struct UnexpectedDefaultValueForLifetimeInGenericParameters { | |
| #[primary_span] | |
| #[label("lifetime parameters cannot have default values")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("cannot define duplicate `where` clauses on an item")] | |
| pub(crate) struct MultipleWhereClauses { | |
| #[primary_span] | |
| pub span: Span, | |
| #[label("previous `where` clause starts here")] | |
| pub previous: Span, | |
| #[suggestion( | |
| "consider joining the two `where` clauses into one", | |
| style = "verbose", | |
| code = ",", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub between: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| pub(crate) enum UnexpectedNonterminal { | |
| #[diag("expected an item keyword")] | |
| Item(#[primary_span] Span), | |
| #[diag("expected a statement")] | |
| Statement(#[primary_span] Span), | |
| #[diag("expected ident, found `{$token}`")] | |
| Ident { | |
| #[primary_span] | |
| span: Span, | |
| token: Cow<'static, str>, | |
| }, | |
| #[diag("expected a lifetime, found `{$token}`")] | |
| Lifetime { | |
| #[primary_span] | |
| span: Span, | |
| token: Cow<'static, str>, | |
| }, | |
| } | |
| #[derive(Diagnostic)] | |
| pub(crate) enum TopLevelOrPatternNotAllowed { | |
| #[diag("`let` bindings require top-level or-patterns in parentheses")] | |
| LetBinding { | |
| #[primary_span] | |
| span: Span, | |
| #[subdiagnostic] | |
| sub: Option<TopLevelOrPatternNotAllowedSugg>, | |
| }, | |
| #[diag("function parameters require top-level or-patterns in parentheses")] | |
| FunctionParameter { | |
| #[primary_span] | |
| span: Span, | |
| #[subdiagnostic] | |
| sub: Option<TopLevelOrPatternNotAllowedSugg>, | |
| }, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`{$ident}` cannot be a raw identifier")] | |
| pub(crate) struct CannotBeRawIdent { | |
| #[primary_span] | |
| pub span: Span, | |
| pub ident: Symbol, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`{$ident}` cannot be a raw lifetime")] | |
| pub(crate) struct CannotBeRawLifetime { | |
| #[primary_span] | |
| pub span: Span, | |
| pub ident: Symbol, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("lifetimes cannot use keyword names")] | |
| pub(crate) struct KeywordLifetime { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("labels cannot use keyword names")] | |
| pub(crate) struct KeywordLabel { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "bare CR not allowed in {$block -> | |
| [true] block doc-comment | |
| *[false] doc-comment | |
| }" | |
| )] | |
| pub(crate) struct CrDocComment { | |
| #[primary_span] | |
| pub span: Span, | |
| pub block: bool, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("no valid digits found for number", code = E0768)] | |
| pub(crate) struct NoDigitsLiteral { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("invalid digit for a base {$base} literal")] | |
| pub(crate) struct InvalidDigitLiteral { | |
| #[primary_span] | |
| pub span: Span, | |
| pub base: u32, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected at least one digit in exponent")] | |
| pub(crate) struct EmptyExponentFloat { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("{$base} float literal is not supported")] | |
| pub(crate) struct FloatLiteralUnsupportedBase { | |
| #[primary_span] | |
| pub span: Span, | |
| pub base: &'static str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("prefix `{$prefix}` is unknown")] | |
| #[note("prefixed identifiers and literals are reserved since Rust 2021")] | |
| pub(crate) struct UnknownPrefix<'a> { | |
| #[primary_span] | |
| #[label("unknown prefix")] | |
| pub span: Span, | |
| pub prefix: &'a str, | |
| #[subdiagnostic] | |
| pub sugg: Option<UnknownPrefixSugg>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[note("macros cannot expand to {$adt_ty} fields")] | |
| pub(crate) struct MacroExpandsToAdtField<'a> { | |
| pub adt_ty: &'a str, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum UnknownPrefixSugg { | |
| #[suggestion( | |
| "use `br` for a raw byte string", | |
| code = "br", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| UseBr(#[primary_span] Span), | |
| #[suggestion( | |
| "use `cr` for a raw C-string", | |
| code = "cr", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| UseCr(#[primary_span] Span), | |
| #[suggestion( | |
| "consider inserting whitespace here", | |
| code = " ", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| Whitespace(#[primary_span] Span), | |
| #[multipart_suggestion( | |
| "if you meant to write a string literal, use double quotes", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| MeantStr { | |
| #[suggestion_part(code = "\"")] | |
| start: Span, | |
| #[suggestion_part(code = "\"")] | |
| end: Span, | |
| }, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("reserved multi-hash token is forbidden")] | |
| #[note("sequences of two or more # are reserved for future use since Rust 2024")] | |
| pub(crate) struct ReservedMultihash { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sugg: Option<GuardedStringSugg>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("invalid string literal")] | |
| #[note("unprefixed guarded string literals are reserved for future use since Rust 2024")] | |
| pub(crate) struct ReservedString { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sugg: Option<GuardedStringSugg>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[suggestion( | |
| "consider inserting whitespace here", | |
| code = " ", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| pub(crate) struct GuardedStringSugg(#[primary_span] pub Span); | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "too many `#` symbols: raw strings may be delimited by up to 255 `#` symbols, but found {$num}" | |
| )] | |
| pub(crate) struct TooManyHashes { | |
| #[primary_span] | |
| pub span: Span, | |
| pub num: u32, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unknown start of token: {$escaped}")] | |
| pub(crate) struct UnknownTokenStart { | |
| #[primary_span] | |
| pub span: Span, | |
| pub escaped: String, | |
| #[subdiagnostic] | |
| pub sugg: Option<TokenSubstitution>, | |
| #[help( | |
| "source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used" | |
| )] | |
| pub null: bool, | |
| #[subdiagnostic] | |
| pub repeat: Option<UnknownTokenRepeat>, | |
| #[help("invisible characters like '{$escaped}' are not usually visible in text editors")] | |
| pub invisible: bool, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum TokenSubstitution { | |
| #[suggestion( | |
| "Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Double Quotation Mark) look like '{$ascii_str}' ({$ascii_name}), but are not", | |
| code = "{suggestion}", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| DirectedQuotes { | |
| #[primary_span] | |
| span: Span, | |
| suggestion: String, | |
| ascii_str: &'static str, | |
| ascii_name: &'static str, | |
| }, | |
| #[suggestion( | |
| "Unicode character '{$ch}' ({$u_name}) looks like '{$ascii_str}' ({$ascii_name}), but it is not", | |
| code = "{suggestion}", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| Other { | |
| #[primary_span] | |
| span: Span, | |
| suggestion: String, | |
| ch: String, | |
| u_name: &'static str, | |
| ascii_str: &'static str, | |
| ascii_name: &'static str, | |
| }, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[note( | |
| "character appears {$repeats -> | |
| [one] once more | |
| *[other] {$repeats} more times | |
| }" | |
| )] | |
| pub(crate) struct UnknownTokenRepeat { | |
| pub repeats: usize, | |
| } | |
| #[derive(Diagnostic)] | |
| pub(crate) enum UnescapeError { | |
| #[diag("invalid unicode character escape")] | |
| #[help( | |
| "unicode escape must {$surrogate -> | |
| [true] not be a surrogate | |
| *[false] be at most 10FFFF | |
| }" | |
| )] | |
| InvalidUnicodeEscape { | |
| #[primary_span] | |
| #[label("invalid escape")] | |
| span: Span, | |
| surrogate: bool, | |
| }, | |
| #[diag( | |
| "{$byte -> | |
| [true] byte | |
| *[false] character | |
| } constant must be escaped: `{$escaped_msg}`" | |
| )] | |
| EscapeOnlyChar { | |
| #[primary_span] | |
| span: Span, | |
| #[suggestion( | |
| "escape the character", | |
| applicability = "machine-applicable", | |
| code = "{escaped_sugg}", | |
| style = "verbose" | |
| )] | |
| char_span: Span, | |
| escaped_sugg: String, | |
| escaped_msg: String, | |
| byte: bool, | |
| }, | |
| #[diag( | |
| r#"{$double_quotes -> | |
| [true] bare CR not allowed in string, use `\r` instead | |
| *[false] character constant must be escaped: `\r` | |
| }"# | |
| )] | |
| BareCr { | |
| #[primary_span] | |
| #[suggestion( | |
| "escape the character", | |
| applicability = "machine-applicable", | |
| code = "\\r", | |
| style = "verbose" | |
| )] | |
| span: Span, | |
| double_quotes: bool, | |
| }, | |
| #[diag("bare CR not allowed in raw string")] | |
| BareCrRawString(#[primary_span] Span), | |
| #[diag("numeric character escape is too short")] | |
| TooShortHexEscape(#[primary_span] Span), | |
| #[diag( | |
| "invalid character in {$is_hex -> | |
| [true] numeric character | |
| *[false] unicode | |
| } escape: `{$ch}`" | |
| )] | |
| InvalidCharInEscape { | |
| #[primary_span] | |
| #[label( | |
| "invalid character in {$is_hex -> | |
| [true] numeric character | |
| *[false] unicode | |
| } escape" | |
| )] | |
| span: Span, | |
| is_hex: bool, | |
| ch: String, | |
| }, | |
| #[diag("invalid start of unicode escape: `_`")] | |
| LeadingUnderscoreUnicodeEscape { | |
| #[primary_span] | |
| #[label("invalid start of unicode escape")] | |
| span: Span, | |
| ch: String, | |
| }, | |
| #[diag("overlong unicode escape")] | |
| OverlongUnicodeEscape( | |
| #[primary_span] | |
| #[label("must have at most 6 hex digits")] | |
| Span, | |
| ), | |
| #[diag("unterminated unicode escape")] | |
| UnclosedUnicodeEscape( | |
| #[primary_span] | |
| #[label(r#"missing a closing `{"}"}`"#)] | |
| Span, | |
| #[suggestion( | |
| "terminate the unicode escape", | |
| code = "}}", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| Span, | |
| ), | |
| #[diag("incorrect unicode escape sequence")] | |
| NoBraceInUnicodeEscape { | |
| #[primary_span] | |
| span: Span, | |
| #[label("incorrect unicode escape sequence")] | |
| label: Option<Span>, | |
| #[subdiagnostic] | |
| sub: NoBraceUnicodeSub, | |
| }, | |
| #[diag("unicode escape in byte string")] | |
| #[help("unicode escape sequences cannot be used as a byte or in a byte string")] | |
| UnicodeEscapeInByte( | |
| #[primary_span] | |
| #[label("unicode escape in byte string")] | |
| Span, | |
| ), | |
| #[diag("empty unicode escape")] | |
| EmptyUnicodeEscape( | |
| #[primary_span] | |
| #[label("this escape must have at least 1 hex digit")] | |
| Span, | |
| ), | |
| #[diag("empty character literal")] | |
| ZeroChars( | |
| #[primary_span] | |
| #[label("empty character literal")] | |
| Span, | |
| ), | |
| #[diag("invalid trailing slash in literal")] | |
| LoneSlash( | |
| #[primary_span] | |
| #[label("invalid trailing slash in literal")] | |
| Span, | |
| ), | |
| #[diag("whitespace symbol '{$ch}' is not skipped")] | |
| UnskippedWhitespace { | |
| #[primary_span] | |
| span: Span, | |
| #[label("whitespace symbol '{$ch}' is not skipped")] | |
| char_span: Span, | |
| ch: String, | |
| }, | |
| #[diag("multiple lines skipped by escaped newline")] | |
| MultipleSkippedLinesWarning( | |
| #[primary_span] | |
| #[label("skipping everything up to and including this point")] | |
| Span, | |
| ), | |
| #[diag("character literal may only contain one codepoint")] | |
| MoreThanOneChar { | |
| #[primary_span] | |
| span: Span, | |
| #[subdiagnostic] | |
| note: Option<MoreThanOneCharNote>, | |
| #[subdiagnostic] | |
| suggestion: MoreThanOneCharSugg, | |
| }, | |
| #[diag("null characters in C string literals are not supported")] | |
| NulInCStr { | |
| #[primary_span] | |
| span: Span, | |
| }, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum MoreThanOneCharSugg { | |
| #[suggestion( | |
| "consider using the normalized form `{$ch}` of this character", | |
| code = "{normalized}", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| NormalizedForm { | |
| #[primary_span] | |
| span: Span, | |
| ch: String, | |
| normalized: String, | |
| }, | |
| #[suggestion( | |
| "consider removing the non-printing characters", | |
| code = "{ch}", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| RemoveNonPrinting { | |
| #[primary_span] | |
| span: Span, | |
| ch: String, | |
| }, | |
| #[suggestion( | |
| "if you meant to write a {$is_byte -> | |
| [true] byte string | |
| *[false] string | |
| } literal, use double quotes", | |
| code = "{sugg}", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| QuotesFull { | |
| #[primary_span] | |
| span: Span, | |
| is_byte: bool, | |
| sugg: String, | |
| }, | |
| #[multipart_suggestion( | |
| "if you meant to write a {$is_byte -> | |
| [true] byte string | |
| *[false] string | |
| } literal, use double quotes", | |
| applicability = "machine-applicable" | |
| )] | |
| Quotes { | |
| #[suggestion_part(code = "{prefix}\"")] | |
| start: Span, | |
| #[suggestion_part(code = "\"")] | |
| end: Span, | |
| is_byte: bool, | |
| prefix: &'static str, | |
| }, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum MoreThanOneCharNote { | |
| #[note( | |
| "this `{$chr}` is followed by the combining {$len -> | |
| [one] mark | |
| *[other] marks | |
| } `{$escaped_marks}`" | |
| )] | |
| AllCombining { | |
| #[primary_span] | |
| span: Span, | |
| chr: String, | |
| len: usize, | |
| escaped_marks: String, | |
| }, | |
| #[note("there are non-printing characters, the full sequence is `{$escaped}`")] | |
| NonPrinting { | |
| #[primary_span] | |
| span: Span, | |
| escaped: String, | |
| }, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum NoBraceUnicodeSub { | |
| #[suggestion( | |
| "format of unicode escape sequences uses braces", | |
| code = "{suggestion}", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| Suggestion { | |
| #[primary_span] | |
| span: Span, | |
| suggestion: String, | |
| }, | |
| #[help(r#"format of unicode escape sequences is `\u{"{...}"}`"#)] | |
| Help, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion("wrap the pattern in parentheses", applicability = "machine-applicable")] | |
| pub(crate) struct WrapInParens { | |
| #[suggestion_part(code = "(")] | |
| pub(crate) lo: Span, | |
| #[suggestion_part(code = ")")] | |
| pub(crate) hi: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum TopLevelOrPatternNotAllowedSugg { | |
| #[suggestion( | |
| "remove the `|`", | |
| code = "", | |
| applicability = "machine-applicable", | |
| style = "tool-only" | |
| )] | |
| RemoveLeadingVert { | |
| #[primary_span] | |
| span: Span, | |
| }, | |
| WrapInParens { | |
| #[primary_span] | |
| span: Span, | |
| #[subdiagnostic] | |
| suggestion: WrapInParens, | |
| }, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected `||` before function parameter")] | |
| #[note("alternatives in or-patterns are separated with `|`, not `||`")] | |
| pub(crate) struct UnexpectedVertVertBeforeFunctionParam { | |
| #[primary_span] | |
| #[suggestion( | |
| "remove the `||`", | |
| code = "", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected token `||` in pattern")] | |
| pub(crate) struct UnexpectedVertVertInPattern { | |
| #[primary_span] | |
| #[suggestion( | |
| "use a single `|` to separate multiple alternative patterns", | |
| code = "|", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| #[label("while parsing this or-pattern starting here")] | |
| pub start: Option<Span>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[suggestion( | |
| "a trailing `{$token}` is not allowed in an or-pattern", | |
| code = "", | |
| applicability = "machine-applicable", | |
| style = "tool-only" | |
| )] | |
| pub(crate) struct TrailingVertSuggestion { | |
| #[primary_span] | |
| pub span: Span, | |
| pub token: Cow<'static, str>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("a trailing `{$token}` is not allowed in an or-pattern")] | |
| pub(crate) struct TrailingVertNotAllowed { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub suggestion: TrailingVertSuggestion, | |
| #[label("while parsing this or-pattern starting here")] | |
| pub start: Option<Span>, | |
| pub token: Cow<'static, str>, | |
| #[note("alternatives in or-patterns are separated with `|`, not `||`")] | |
| pub note_double_vert: bool, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected `...`")] | |
| pub(crate) struct DotDotDotRestPattern { | |
| #[primary_span] | |
| #[label("not a valid pattern")] | |
| pub span: Span, | |
| #[suggestion( | |
| "for a rest pattern, use `..` instead of `...`", | |
| style = "verbose", | |
| code = "..", | |
| applicability = "machine-applicable" | |
| )] | |
| pub suggestion: Option<Span>, | |
| #[note( | |
| "only `extern \"C\"` and `extern \"C-unwind\"` functions may have a C variable argument list" | |
| )] | |
| pub var_args: Option<()>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("pattern on wrong side of `@`")] | |
| pub(crate) struct PatternOnWrongSideOfAt { | |
| #[primary_span] | |
| #[suggestion( | |
| "switch the order", | |
| code = "{whole_pat}", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub whole_span: Span, | |
| pub whole_pat: String, | |
| #[label("pattern on the left, should be on the right")] | |
| pub pattern: Span, | |
| #[label("binding on the right, should be on the left")] | |
| pub binding: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("left-hand side of `@` must be a binding")] | |
| #[note("bindings are `x`, `mut x`, `ref x`, and `ref mut x`")] | |
| pub(crate) struct ExpectedBindingLeftOfAt { | |
| #[primary_span] | |
| pub whole_span: Span, | |
| #[label("interpreted as a pattern, not a binding")] | |
| pub lhs: Span, | |
| #[label("also a pattern")] | |
| pub rhs: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "add parentheses to clarify the precedence", | |
| applicability = "machine-applicable" | |
| )] | |
| pub(crate) struct ParenRangeSuggestion { | |
| #[suggestion_part(code = "(")] | |
| pub lo: Span, | |
| #[suggestion_part(code = ")")] | |
| pub hi: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("the range pattern here has ambiguous interpretation")] | |
| pub(crate) struct AmbiguousRangePattern { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub suggestion: ParenRangeSuggestion, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected lifetime `{$symbol}` in pattern")] | |
| pub(crate) struct UnexpectedLifetimeInPattern { | |
| #[primary_span] | |
| pub span: Span, | |
| pub symbol: Symbol, | |
| #[suggestion( | |
| "remove the lifetime", | |
| code = "", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub suggestion: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| pub(crate) enum InvalidMutInPattern { | |
| #[diag("`mut` must be attached to each individual binding")] | |
| #[note("`mut` may be followed by `variable` and `variable @ pattern`")] | |
| NestedIdent { | |
| #[primary_span] | |
| #[suggestion( | |
| "add `mut` to each binding", | |
| code = "{pat}", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| span: Span, | |
| pat: String, | |
| }, | |
| #[diag("`mut` must be followed by a named binding")] | |
| #[note("`mut` may be followed by `variable` and `variable @ pattern`")] | |
| NonIdent { | |
| #[primary_span] | |
| #[suggestion( | |
| "remove the `mut` prefix", | |
| code = "", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| span: Span, | |
| }, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`mut` on a binding may not be repeated")] | |
| pub(crate) struct RepeatedMutInPattern { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "remove the additional `mut`s", | |
| code = "", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub suggestion: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("range-to patterns with `...` are not allowed")] | |
| pub(crate) struct DotDotDotRangeToPatternNotAllowed { | |
| #[primary_span] | |
| #[suggestion( | |
| "use `..=` instead", | |
| style = "verbose", | |
| code = "..=", | |
| applicability = "machine-applicable" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected identifier, found enum pattern")] | |
| pub(crate) struct EnumPatternInsteadOfIdentifier { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`@ ..` is not supported in struct patterns")] | |
| pub(crate) struct AtDotDotInStructPattern { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "bind to each field separately or, if you don't need them, just remove `{$ident} @`", | |
| code = "", | |
| style = "verbose", | |
| applicability = "machine-applicable" | |
| )] | |
| pub remove: Span, | |
| pub ident: Ident, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected `@` in struct pattern")] | |
| #[note("struct patterns use `field: pattern` syntax to bind to fields")] | |
| #[help( | |
| "consider replacing `new_name @ field_name` with `field_name: new_name` if that is what you intended" | |
| )] | |
| pub(crate) struct AtInStructPattern { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected field pattern, found `{$token_str}`")] | |
| pub(crate) struct DotDotDotForRemainingFields { | |
| #[primary_span] | |
| #[suggestion( | |
| "to omit remaining fields, use `..`", | |
| code = "..", | |
| style = "verbose", | |
| applicability = "machine-applicable" | |
| )] | |
| pub span: Span, | |
| pub token_str: Cow<'static, str>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected `,`")] | |
| pub(crate) struct ExpectedCommaAfterPatternField { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "expected {$is_bound -> | |
| [true] a pattern range bound | |
| *[false] a pattern | |
| }, found an expression" | |
| )] | |
| #[note( | |
| "arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>" | |
| )] | |
| pub(crate) struct UnexpectedExpressionInPattern { | |
| /// The unexpected expr's span. | |
| #[primary_span] | |
| #[label("not a pattern")] | |
| pub span: Span, | |
| /// Was a `RangePatternBound` expected? | |
| pub is_bound: bool, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum UnexpectedExpressionInPatternSugg { | |
| #[multipart_suggestion( | |
| "consider moving the expression to a match arm guard", | |
| applicability = "maybe-incorrect" | |
| )] | |
| CreateGuard { | |
| /// Where to put the suggested identifier. | |
| #[suggestion_part(code = "{ident}")] | |
| ident_span: Span, | |
| /// Where to put the match arm. | |
| #[suggestion_part(code = " if {ident} == {expr}")] | |
| pat_hi: Span, | |
| /// The suggested identifier. | |
| ident: String, | |
| /// The unexpected expression. | |
| expr: String, | |
| }, | |
| #[multipart_suggestion( | |
| "consider moving the expression to the match arm guard", | |
| applicability = "maybe-incorrect" | |
| )] | |
| UpdateGuard { | |
| /// Where to put the suggested identifier. | |
| #[suggestion_part(code = "{ident}")] | |
| ident_span: Span, | |
| /// The beginning of the match arm guard's expression (insert a `(` if `Some`). | |
| #[suggestion_part(code = "(")] | |
| guard_lo: Option<Span>, | |
| /// The end of the match arm guard's expression. | |
| #[suggestion_part(code = "{guard_hi_paren} && {ident} == {expr}")] | |
| guard_hi: Span, | |
| /// Either `")"` or `""`. | |
| guard_hi_paren: &'static str, | |
| /// The suggested identifier. | |
| ident: String, | |
| /// The unexpected expression. | |
| expr: String, | |
| }, | |
| #[multipart_suggestion( | |
| "consider extracting the expression into a `const`", | |
| applicability = "has-placeholders" | |
| )] | |
| Const { | |
| /// Where to put the extracted constant declaration. | |
| #[suggestion_part(code = "{indentation}const {ident}: /* Type */ = {expr};\n")] | |
| stmt_lo: Span, | |
| /// Where to put the suggested identifier. | |
| #[suggestion_part(code = "{ident}")] | |
| ident_span: Span, | |
| /// The suggested identifier. | |
| ident: String, | |
| /// The unexpected expression. | |
| expr: String, | |
| /// The statement's block's indentation. | |
| indentation: String, | |
| }, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("range pattern bounds cannot have parentheses")] | |
| pub(crate) struct UnexpectedParenInRangePat { | |
| #[primary_span] | |
| pub span: Vec<Span>, | |
| #[subdiagnostic] | |
| pub sugg: UnexpectedParenInRangePatSugg, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion("remove these parentheses", applicability = "machine-applicable")] | |
| pub(crate) struct UnexpectedParenInRangePatSugg { | |
| #[suggestion_part(code = "")] | |
| pub start_span: Span, | |
| #[suggestion_part(code = "")] | |
| pub end_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("return types are denoted using `->`")] | |
| pub(crate) struct ReturnTypesUseThinArrow { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "use `->` instead", | |
| style = "verbose", | |
| code = " -> ", | |
| applicability = "machine-applicable" | |
| )] | |
| pub suggestion: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("lifetimes must be followed by `+` to form a trait object type")] | |
| pub(crate) struct NeedPlusAfterTraitObjectLifetime { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "consider adding a trait bound after the potential lifetime bound", | |
| code = " + /* Trait */", | |
| applicability = "has-placeholders" | |
| )] | |
| pub suggestion: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected `mut` or `const` keyword in raw pointer type")] | |
| pub(crate) struct ExpectedMutOrConstInRawPointerType { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "add `mut` or `const` here", | |
| code("mut ", "const "), | |
| applicability = "has-placeholders", | |
| style = "verbose" | |
| )] | |
| pub after_asterisk: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("lifetime must precede `mut`")] | |
| pub(crate) struct LifetimeAfterMut { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "place the lifetime before `mut`", | |
| code = "&{snippet} mut", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| pub suggest_lifetime: Option<Span>, | |
| pub snippet: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`mut` must precede `dyn`")] | |
| pub(crate) struct DynAfterMut { | |
| #[primary_span] | |
| #[suggestion( | |
| "place `mut` before `dyn`", | |
| code = "&mut dyn", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("an `fn` pointer type cannot be `const`")] | |
| #[note("allowed qualifiers are: `unsafe` and `extern`")] | |
| pub(crate) struct FnPointerCannotBeConst { | |
| #[primary_span] | |
| #[label("`const` because of this")] | |
| pub span: Span, | |
| #[suggestion( | |
| "remove the `const` qualifier", | |
| code = "", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| pub suggestion: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("an `fn` pointer type cannot be `async`")] | |
| #[note("allowed qualifiers are: `unsafe` and `extern`")] | |
| pub(crate) struct FnPointerCannotBeAsync { | |
| #[primary_span] | |
| #[label("`async` because of this")] | |
| pub span: Span, | |
| #[suggestion( | |
| "remove the `async` qualifier", | |
| code = "", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| pub suggestion: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("C-variadic type `...` may not be nested inside another type", code = E0743)] | |
| pub(crate) struct NestedCVariadicType { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected `...`")] | |
| #[note( | |
| "only `extern \"C\"` and `extern \"C-unwind\"` functions may have a C variable argument list" | |
| )] | |
| pub(crate) struct InvalidCVariadicType { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("invalid `dyn` keyword")] | |
| #[help("`dyn` is only needed at the start of a trait `+`-separated list")] | |
| pub(crate) struct InvalidDynKeyword { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "remove this keyword", | |
| code = "", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub suggestion: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum HelpUseLatestEdition { | |
| #[help("set `edition = \"{$edition}\"` in `Cargo.toml`")] | |
| #[note("for more on editions, read https://doc.rust-lang.org/edition-guide")] | |
| Cargo { edition: Edition }, | |
| #[help("pass `--edition {$edition}` to `rustc`")] | |
| #[note("for more on editions, read https://doc.rust-lang.org/edition-guide")] | |
| Standalone { edition: Edition }, | |
| } | |
| impl HelpUseLatestEdition { | |
| pub(crate) fn new() -> Self { | |
| let edition = LATEST_STABLE_EDITION; | |
| if rustc_session::utils::was_invoked_from_cargo() { | |
| Self::Cargo { edition } | |
| } else { | |
| Self::Standalone { edition } | |
| } | |
| } | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`box_syntax` has been removed")] | |
| pub(crate) struct BoxSyntaxRemoved { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sugg: AddBoxNew, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "use `Box::new()` instead", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub(crate) struct AddBoxNew { | |
| #[suggestion_part(code = "Box::new(")] | |
| pub box_kw_and_lo: Span, | |
| #[suggestion_part(code = ")")] | |
| pub hi: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("return type not allowed with return type notation")] | |
| pub(crate) struct BadReturnTypeNotationOutput { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "remove the return type", | |
| code = "", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| pub suggestion: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("bounds on associated types do not belong here")] | |
| pub(crate) struct BadAssocTypeBounds { | |
| #[primary_span] | |
| #[label("belongs in `where` clause")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("trailing attribute after generic parameter")] | |
| pub(crate) struct AttrAfterGeneric { | |
| #[primary_span] | |
| #[label("attributes must go before parameters")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("attribute without generic parameters")] | |
| pub(crate) struct AttrWithoutGenerics { | |
| #[primary_span] | |
| #[label("attributes are only permitted when preceding parameters")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("generic parameters on `where` clauses are reserved for future use")] | |
| pub(crate) struct WhereOnGenerics { | |
| #[primary_span] | |
| #[label("currently unsupported")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unexpected generic arguments in path")] | |
| pub(crate) struct GenericsInPath { | |
| #[primary_span] | |
| pub span: Vec<Span>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("lifetimes are not permitted in this context")] | |
| #[help("if you meant to specify a trait object, write `dyn /* Trait */ + {$lifetime}`")] | |
| pub(crate) struct LifetimeInEqConstraint { | |
| #[primary_span] | |
| #[label("lifetime is not allowed here")] | |
| pub span: Span, | |
| pub lifetime: Ident, | |
| #[label("this introduces an associated item binding")] | |
| pub binding_label: Span, | |
| #[suggestion( | |
| "you might have meant to write a bound here", | |
| style = "verbose", | |
| applicability = "maybe-incorrect", | |
| code = ": " | |
| )] | |
| pub colon_sugg: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`{$modifier}` may only modify trait bounds, not lifetime bounds")] | |
| pub(crate) struct ModifierLifetime { | |
| #[primary_span] | |
| #[suggestion( | |
| "remove the `{$modifier}`", | |
| style = "tool-only", | |
| applicability = "maybe-incorrect", | |
| code = "" | |
| )] | |
| pub span: Span, | |
| pub modifier: &'static str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("underscore literal suffix is not allowed")] | |
| pub(crate) struct UnderscoreLiteralSuffix { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected a label, found an identifier")] | |
| pub(crate) struct ExpectedLabelFoundIdent { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "labels start with a tick", | |
| code = "'", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub start: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("{$article} {$descr} cannot be `default`")] | |
| #[note("only associated `fn`, `const`, and `type` items can be `default`")] | |
| pub(crate) struct InappropriateDefault { | |
| #[primary_span] | |
| #[label("`default` because of this")] | |
| pub span: Span, | |
| pub article: &'static str, | |
| pub descr: &'static str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected item, found {$token_name}")] | |
| pub(crate) struct RecoverImportAsUse { | |
| #[primary_span] | |
| #[suggestion( | |
| "items are imported using the `use` keyword", | |
| code = "use", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| pub token_name: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("{$article} {$descr} cannot be `final`")] | |
| #[note("only associated functions in traits can be `final`")] | |
| pub(crate) struct InappropriateFinal { | |
| #[primary_span] | |
| #[label("`final` because of this")] | |
| pub span: Span, | |
| pub article: &'static str, | |
| pub descr: &'static str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected `::`, found `:`")] | |
| #[note("import paths are delimited using `::`")] | |
| pub(crate) struct SingleColonImportPath { | |
| #[primary_span] | |
| #[suggestion( | |
| "use double colon", | |
| code = "::", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("{$descr} is not supported in {$ctx}")] | |
| pub(crate) struct BadItemKind { | |
| #[primary_span] | |
| pub span: Span, | |
| pub descr: &'static str, | |
| pub ctx: &'static str, | |
| #[help("consider moving the {$descr} out to a nearby module scope")] | |
| pub help: bool, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected `!` after `macro_rules`")] | |
| pub(crate) struct MacroRulesMissingBang { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion("add a `!`", code = "!", applicability = "machine-applicable", style = "verbose")] | |
| pub hi: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("macro names aren't followed by a `!`")] | |
| pub(crate) struct MacroNameRemoveBang { | |
| #[primary_span] | |
| #[suggestion( | |
| "remove the `!`", | |
| code = "", | |
| applicability = "machine-applicable", | |
| style = "short" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("can't qualify macro_rules invocation with `{$vis}`")] | |
| pub(crate) struct MacroRulesVisibility<'a> { | |
| #[primary_span] | |
| #[suggestion( | |
| "try exporting the macro", | |
| code = "#[macro_export]", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| pub vis: &'a str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("can't qualify macro invocation with `pub`")] | |
| #[help("try adjusting the macro to put `{$vis}` inside the invocation")] | |
| pub(crate) struct MacroInvocationVisibility<'a> { | |
| #[primary_span] | |
| #[suggestion( | |
| "remove the visibility", | |
| code = "", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| pub vis: &'a str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`{$kw_str}` definition cannot be nested inside `{$keyword}`")] | |
| pub(crate) struct NestedAdt<'a> { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "consider creating a new `{$kw_str}` definition instead of nesting", | |
| code = "", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| pub item: Span, | |
| pub keyword: &'a str, | |
| pub kw_str: Cow<'a, str>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("function body cannot be `= expression;`")] | |
| pub(crate) struct FunctionBodyEqualsExpr { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sugg: FunctionBodyEqualsExprSugg, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| r#"surround the expression with `{"{"}` and `{"}"}` instead of `=` and `;`"#, | |
| applicability = "machine-applicable" | |
| )] | |
| pub(crate) struct FunctionBodyEqualsExprSugg { | |
| #[suggestion_part(code = "{{")] | |
| pub eq: Span, | |
| #[suggestion_part(code = " }}")] | |
| pub semi: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected pattern, found {$descr}")] | |
| pub(crate) struct BoxNotPat { | |
| #[primary_span] | |
| pub span: Span, | |
| #[note("`box` is a reserved keyword")] | |
| pub kw: Span, | |
| #[suggestion( | |
| "escape `box` to use it as an identifier", | |
| code = "r#", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| pub lo: Span, | |
| pub descr: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "unmatched angle {$plural -> | |
| [true] brackets | |
| *[false] bracket | |
| }" | |
| )] | |
| pub(crate) struct UnmatchedAngle { | |
| #[primary_span] | |
| #[suggestion( | |
| "remove extra angle {$plural -> | |
| [true] brackets | |
| *[false] bracket | |
| }", | |
| code = "", | |
| applicability = "machine-applicable", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| pub plural: bool, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected `+` between lifetime and {$sym}")] | |
| pub(crate) struct MissingPlusBounds { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion("add `+`", code = " +", applicability = "maybe-incorrect", style = "verbose")] | |
| pub hi: Span, | |
| pub sym: Symbol, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("incorrect parentheses around trait bounds")] | |
| pub(crate) struct IncorrectParensTraitBounds { | |
| #[primary_span] | |
| pub span: Vec<Span>, | |
| #[subdiagnostic] | |
| pub sugg: IncorrectParensTraitBoundsSugg, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion("fix the parentheses", applicability = "machine-applicable")] | |
| pub(crate) struct IncorrectParensTraitBoundsSugg { | |
| #[suggestion_part(code = " ")] | |
| pub wrong_span: Span, | |
| #[suggestion_part(code = "(")] | |
| pub new_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("keyword `{$kw}` is written in the wrong case")] | |
| pub(crate) struct KwBadCase<'a> { | |
| #[primary_span] | |
| #[suggestion( | |
| "write it in {$case}", | |
| code = "{kw}", | |
| style = "verbose", | |
| applicability = "machine-applicable" | |
| )] | |
| pub span: Span, | |
| pub kw: &'a str, | |
| pub case: Case, | |
| } | |
| pub(crate) enum Case { | |
| Upper, | |
| Lower, | |
| Mixed, | |
| } | |
| impl IntoDiagArg for Case { | |
| fn into_diag_arg(self, path: &mut Option<PathBuf>) -> DiagArgValue { | |
| match self { | |
| Case::Upper => "uppercase", | |
| Case::Lower => "lowercase", | |
| Case::Mixed => "the correct case", | |
| } | |
| .into_diag_arg(path) | |
| } | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unknown `builtin #` construct `{$name}`")] | |
| pub(crate) struct UnknownBuiltinConstruct { | |
| #[primary_span] | |
| pub span: Span, | |
| pub name: Ident, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected identifier after `builtin #`")] | |
| pub(crate) struct ExpectedBuiltinIdent { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("static items may not have generic parameters")] | |
| pub(crate) struct StaticWithGenerics { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("where clauses are not allowed before const item bodies")] | |
| pub(crate) struct WhereClauseBeforeConstBody { | |
| #[primary_span] | |
| #[label("unexpected where clause")] | |
| pub span: Span, | |
| #[label("while parsing this const item")] | |
| pub name: Span, | |
| #[label("the item body")] | |
| pub body: Span, | |
| #[subdiagnostic] | |
| pub sugg: Option<WhereClauseBeforeConstBodySugg>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "move the body before the where clause", | |
| applicability = "machine-applicable" | |
| )] | |
| pub(crate) struct WhereClauseBeforeConstBodySugg { | |
| #[suggestion_part(code = "= {snippet} ")] | |
| pub left: Span, | |
| pub snippet: String, | |
| #[suggestion_part(code = "")] | |
| pub right: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("generic args in patterns require the turbofish syntax")] | |
| pub(crate) struct GenericArgsInPatRequireTurbofishSyntax { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments", | |
| style = "verbose", | |
| code = "::", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub suggest_turbofish: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`for<...>` expected after `{$kw}`, not before")] | |
| pub(crate) struct TransposeDynOrImpl<'a> { | |
| #[primary_span] | |
| pub span: Span, | |
| pub kw: &'a str, | |
| #[subdiagnostic] | |
| pub sugg: TransposeDynOrImplSugg<'a>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion("move `{$kw}` before the `for<...>`", applicability = "machine-applicable")] | |
| pub(crate) struct TransposeDynOrImplSugg<'a> { | |
| #[suggestion_part(code = "")] | |
| pub removal_span: Span, | |
| #[suggestion_part(code = "{kw} ")] | |
| pub insertion_span: Span, | |
| pub kw: &'a str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("array indexing not supported in offset_of")] | |
| pub(crate) struct ArrayIndexInOffsetOf(#[primary_span] pub Span); | |
| #[derive(Diagnostic)] | |
| #[diag("offset_of expects dot-separated field and variant names")] | |
| pub(crate) struct InvalidOffsetOf(#[primary_span] pub Span); | |
| #[derive(Diagnostic)] | |
| #[diag("`async` trait implementations are unsupported")] | |
| pub(crate) struct AsyncImpl { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`->` is not valid syntax for field accesses and method calls")] | |
| #[help( | |
| "the `.` operator will automatically dereference the value, except if the value is a raw pointer" | |
| )] | |
| pub(crate) struct ExprRArrowCall { | |
| #[primary_span] | |
| #[suggestion( | |
| "try using `.` instead", | |
| style = "verbose", | |
| applicability = "machine-applicable", | |
| code = "." | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("attributes are not allowed on range expressions starting with `..`")] | |
| pub(crate) struct DotDotRangeAttribute { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`for<...>` binder should be placed before trait bound modifiers")] | |
| pub(crate) struct BinderBeforeModifiers { | |
| #[primary_span] | |
| pub binder_span: Span, | |
| #[label("place the `for<...>` binder before any modifiers")] | |
| pub modifiers_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`for<...>` binder not allowed with `{$polarity}` trait polarity modifier")] | |
| pub(crate) struct BinderAndPolarity { | |
| #[primary_span] | |
| pub polarity_span: Span, | |
| #[label("there is not a well-defined meaning for a higher-ranked `{$polarity}` trait")] | |
| pub binder_span: Span, | |
| pub polarity: &'static str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`{$modifiers_concatenated}` trait not allowed with `{$polarity}` trait polarity modifier")] | |
| pub(crate) struct PolarityAndModifiers { | |
| #[primary_span] | |
| pub polarity_span: Span, | |
| #[label( | |
| "there is not a well-defined meaning for a `{$modifiers_concatenated} {$polarity}` trait" | |
| )] | |
| pub modifiers_span: Span, | |
| pub polarity: &'static str, | |
| pub modifiers_concatenated: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("type not allowed for shorthand `self` parameter")] | |
| pub(crate) struct IncorrectTypeOnSelf { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub move_self_modifier: MoveSelfModifier, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "move the modifiers on `self` to the type", | |
| applicability = "machine-applicable" | |
| )] | |
| pub(crate) struct MoveSelfModifier { | |
| #[suggestion_part(code = "")] | |
| pub removal_span: Span, | |
| #[suggestion_part(code = "{modifier}")] | |
| pub insertion_span: Span, | |
| pub modifier: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("the `{$symbol}` operand cannot be used with `{$macro_name}!`")] | |
| pub(crate) struct AsmUnsupportedOperand<'a> { | |
| #[primary_span] | |
| #[label( | |
| "the `{$symbol}` operand is not meaningful for global-scoped inline assembly, remove it" | |
| )] | |
| pub(crate) span: Span, | |
| pub(crate) symbol: &'a str, | |
| pub(crate) macro_name: &'static str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("_ cannot be used for input operands")] | |
| pub(crate) struct AsmUnderscoreInput { | |
| #[primary_span] | |
| pub(crate) span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected a path for argument to `sym`")] | |
| pub(crate) struct AsmSymNoPath { | |
| #[primary_span] | |
| pub(crate) span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("requires at least a template string argument")] | |
| pub(crate) struct AsmRequiresTemplate { | |
| #[primary_span] | |
| pub(crate) span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected token: `,`")] | |
| pub(crate) struct AsmExpectedComma { | |
| #[primary_span] | |
| #[label("expected `,`")] | |
| pub(crate) span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "expected operand, {$is_inline_asm -> | |
| [false] options | |
| *[true] clobber_abi, options | |
| }, or additional template string" | |
| )] | |
| pub(crate) struct AsmExpectedOther { | |
| #[primary_span] | |
| #[label( | |
| "expected operand, {$is_inline_asm -> | |
| [false] options | |
| *[true] clobber_abi, options | |
| }, or additional template string" | |
| )] | |
| pub(crate) span: Span, | |
| pub(crate) is_inline_asm: bool, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("at least one abi must be provided as an argument to `clobber_abi`")] | |
| pub(crate) struct NonABI { | |
| #[primary_span] | |
| pub(crate) span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected string literal")] | |
| pub(crate) struct AsmExpectedStringLiteral { | |
| #[primary_span] | |
| #[label("not a string literal")] | |
| pub(crate) span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected register class or explicit register")] | |
| pub(crate) struct ExpectedRegisterClassOrExplicitRegister { | |
| #[primary_span] | |
| pub(crate) span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unicode codepoint changing visible direction of text present in {$label}")] | |
| #[note( | |
| "these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen" | |
| )] | |
| pub(crate) struct HiddenUnicodeCodepointsDiag { | |
| pub label: String, | |
| pub count: usize, | |
| #[label( | |
| "this {$label} contains {$count -> | |
| [one] an invisible | |
| *[other] invisible | |
| } unicode text flow control {$count -> | |
| [one] codepoint | |
| *[other] codepoints | |
| }" | |
| )] | |
| pub span_label: Span, | |
| #[subdiagnostic] | |
| pub labels: Option<HiddenUnicodeCodepointsDiagLabels>, | |
| #[subdiagnostic] | |
| pub sub: HiddenUnicodeCodepointsDiagSub, | |
| } | |
| pub(crate) struct HiddenUnicodeCodepointsDiagLabels { | |
| pub spans: Vec<(char, Span)>, | |
| } | |
| impl Subdiagnostic for HiddenUnicodeCodepointsDiagLabels { | |
| fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) { | |
| for (c, span) in self.spans { | |
| diag.span_label(span, format!("{c:?}")); | |
| } | |
| } | |
| } | |
| pub(crate) enum HiddenUnicodeCodepointsDiagSub { | |
| Escape { spans: Vec<(char, Span)> }, | |
| NoEscape { spans: Vec<(char, Span)>, is_doc_comment: bool }, | |
| } | |
| // Used because of multiple multipart_suggestion and note | |
| impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub { | |
| fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) { | |
| match self { | |
| HiddenUnicodeCodepointsDiagSub::Escape { spans } => { | |
| diag.multipart_suggestion_with_style( | |
| msg!("if their presence wasn't intentional, you can remove them"), | |
| spans.iter().map(|(_, span)| (*span, "".to_string())).collect(), | |
| Applicability::MachineApplicable, | |
| SuggestionStyle::HideCodeAlways, | |
| ); | |
| diag.multipart_suggestion( | |
| msg!("if you want to keep them but make them visible in your source code, you can escape them"), | |
| spans | |
| .into_iter() | |
| .map(|(c, span)| { | |
| let c = format!("{c:?}"); | |
| (span, c[1..c.len() - 1].to_string()) | |
| }) | |
| .collect(), | |
| Applicability::MachineApplicable, | |
| ); | |
| } | |
| HiddenUnicodeCodepointsDiagSub::NoEscape { spans, is_doc_comment } => { | |
| // FIXME: in other suggestions we've reversed the inner spans of doc comments. We | |
| // should do the same here to provide the same good suggestions as we do for | |
| // literals above. | |
| diag.arg( | |
| "escaped", | |
| spans | |
| .into_iter() | |
| .map(|(c, _)| format!("{c:?}")) | |
| .collect::<Vec<String>>() | |
| .join(", "), | |
| ); | |
| diag.note(msg!("if their presence wasn't intentional, you can remove them")); | |
| if is_doc_comment { | |
| diag.note(msg!(r#"if you need to keep them and make them explicit in source, rewrite this doc comment as a `#[doc = "..."]` attribute and use Unicode escapes such as {$escaped}"#)); | |
| } else { | |
| diag.note(msg!("if you want to keep them but make them visible in your source code, you can escape them: {$escaped}")); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("missing pattern for `...` argument")] | |
| pub(crate) struct VarargsWithoutPattern { | |
| #[suggestion( | |
| "name the argument, or use `_` to continue ignoring it", | |
| code = "_: ...", | |
| applicability = "machine-applicable" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("only trait impls can be reused")] | |
| pub(crate) struct ImplReuseInherentImpl { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("placeholder `_` is not allowed for the path in struct literals")] | |
| pub(crate) struct StructLiteralPlaceholderPath { | |
| #[primary_span] | |
| #[label("not allowed in struct literals")] | |
| #[suggestion( | |
| "replace it with the correct type", | |
| applicability = "has-placeholders", | |
| code = "/* Type */", | |
| style = "verbose" | |
| )] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("struct literal body without path")] | |
| pub(crate) struct StructLiteralWithoutPathLate { | |
| #[primary_span] | |
| #[label("struct name missing for struct literal")] | |
| pub span: Span, | |
| #[suggestion( | |
| "add the correct type", | |
| applicability = "has-placeholders", | |
| code = "/* Type */ ", | |
| style = "verbose" | |
| )] | |
| pub suggestion_span: Span, | |
| } | |
| /// Used to forbid `let` expressions in certain syntactic locations. | |
| #[derive(Clone, Copy, Subdiagnostic)] | |
| pub(crate) enum ForbiddenLetReason { | |
| /// `let` is not valid and the source environment is not important | |
| OtherForbidden, | |
| /// A let chain with the `||` operator | |
| #[note("`||` operators are not supported in let chain expressions")] | |
| NotSupportedOr(#[primary_span] Span), | |
| /// A let chain with invalid parentheses | |
| /// | |
| /// For example, `let 1 = 1 && (expr && expr)` is allowed | |
| /// but `(let 1 = 1 && (let 1 = 1 && (let 1 = 1))) && let a = 1` is not | |
| #[note("`let`s wrapped in parentheses are not supported in a context with let chains")] | |
| NotSupportedParentheses(#[primary_span] Span), | |
| } | |
| #[derive(Debug, rustc_macros::Subdiagnostic)] | |
| #[suggestion( | |
| "{$is_incorrect_case -> | |
| [true] write keyword `{$similar_kw}` in lowercase | |
| *[false] there is a keyword `{$similar_kw}` with a similar name | |
| }", | |
| applicability = "machine-applicable", | |
| code = "{similar_kw}", | |
| style = "verbose" | |
| )] | |
| pub(crate) struct MisspelledKw { | |
| // We use a String here because `Symbol::into_diag_arg` calls `Symbol::to_ident_string`, which | |
| // prefix the keyword with a `r#` because it aims to print the symbol as an identifier. | |
| pub similar_kw: String, | |
| #[primary_span] | |
| pub span: Span, | |
| pub is_incorrect_case: bool, | |
| } | |
| #[derive(Clone, Copy, Debug, PartialEq, Eq)] | |
| pub(super) enum TokenDescription { | |
| ReservedIdentifier, | |
| Keyword, | |
| ReservedKeyword, | |
| DocComment, | |
| // Expanded metavariables are wrapped in invisible delimiters which aren't | |
| // pretty-printed. In error messages we must handle these specially | |
| // otherwise we get confusing things in messages like "expected `(`, found | |
| // ``". It's better to say e.g. "expected `(`, found type metavariable". | |
| MetaVar(MetaVarKind), | |
| } | |
| impl TokenDescription { | |
| pub(super) fn from_token(token: &Token) -> Option<Self> { | |
| match token.kind { | |
| _ if token.is_special_ident() => Some(TokenDescription::ReservedIdentifier), | |
| _ if token.is_used_keyword() => Some(TokenDescription::Keyword), | |
| _ if token.is_unused_keyword() => Some(TokenDescription::ReservedKeyword), | |
| token::DocComment(..) => Some(TokenDescription::DocComment), | |
| token::OpenInvisible(InvisibleOrigin::MetaVar(kind)) => { | |
| Some(TokenDescription::MetaVar(kind)) | |
| } | |
| _ => None, | |
| } | |
| } | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression" | |
| )] | |
| pub(crate) struct BreakWithLabelAndLoop { | |
| #[subdiagnostic] | |
| pub sub: BreakWithLabelAndLoopSub, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion("wrap this expression in parentheses", applicability = "machine-applicable")] | |
| pub(crate) struct BreakWithLabelAndLoopSub { | |
| #[suggestion_part(code = "(")] | |
| pub left: Span, | |
| #[suggestion_part(code = ")")] | |
| pub right: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("prefix `'r` is reserved")] | |
| pub(crate) struct RawPrefix { | |
| #[label("reserved prefix")] | |
| pub label: Span, | |
| #[suggestion( | |
| "insert whitespace here to avoid this being parsed as a prefix in Rust 2021", | |
| code = " ", | |
| applicability = "machine-applicable" | |
| )] | |
| pub suggestion: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unicode codepoint changing visible direction of text present in comment")] | |
| #[note( | |
| "these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen" | |
| )] | |
| pub(crate) struct UnicodeTextFlow { | |
| #[label( | |
| "{$num_codepoints -> | |
| [1] this comment contains an invisible unicode text flow control codepoint | |
| *[other] this comment contains invisible unicode text flow control codepoints | |
| }" | |
| )] | |
| pub comment_span: Span, | |
| #[subdiagnostic] | |
| pub characters: Vec<UnicodeCharNoteSub>, | |
| #[subdiagnostic] | |
| pub suggestions: Option<UnicodeTextFlowSuggestion>, | |
| pub num_codepoints: usize, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[label("{$c_debug}")] | |
| pub(crate) struct UnicodeCharNoteSub { | |
| #[primary_span] | |
| pub span: Span, | |
| pub c_debug: String, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "if their presence wasn't intentional, you can remove them", | |
| applicability = "machine-applicable", | |
| style = "hidden" | |
| )] | |
| pub(crate) struct UnicodeTextFlowSuggestion { | |
| #[suggestion_part(code = "")] | |
| pub spans: Vec<Span>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("prefix `{$prefix}` is unknown")] | |
| pub(crate) struct ReservedPrefix { | |
| #[label("unknown prefix")] | |
| pub label: Span, | |
| #[suggestion( | |
| "insert whitespace here to avoid this being parsed as a prefix in Rust 2021", | |
| code = " ", | |
| applicability = "machine-applicable" | |
| )] | |
| pub suggestion: Span, | |
| pub prefix: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("will be parsed as a guarded string in Rust 2024")] | |
| pub(crate) struct ReservedStringLint { | |
| #[suggestion( | |
| "insert whitespace here to avoid this being parsed as a guarded string in Rust 2024", | |
| code = " ", | |
| applicability = "machine-applicable" | |
| )] | |
| pub suggestion: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("reserved token in Rust 2024")] | |
| pub(crate) struct ReservedMultihashLint { | |
| #[suggestion( | |
| "insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024", | |
| code = " ", | |
| applicability = "machine-applicable" | |
| )] | |
| pub suggestion: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[suggestion( | |
| "if you meant to write a path, use a double colon", | |
| code = "::", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub(crate) struct UseDoubleColonSuggestion { | |
| #[primary_span] | |
| pub colon: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "if you meant to create a regular struct, use curly braces", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub(crate) struct UseRegularStructSuggestion { | |
| #[suggestion_part(code = " {{ ")] | |
| pub open: Span, | |
| #[suggestion_part(code = " }}")] | |
| pub close: Span, | |
| #[suggestion_part(code = "")] | |
| pub semicolon: Option<Span>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected type parameter, found path `{$path}`")] | |
| pub(crate) struct FoundPathInGenerics { | |
| #[primary_span] | |
| pub span: Span, | |
| pub path: String, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[suggestion( | |
| "you might have meant to bind a type parameter to a trait", | |
| applicability = "maybe-incorrect", | |
| code = "T: " | |
| )] | |
| pub(crate) struct SuggestBindTypeParameter { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[suggestion( | |
| "alternatively, you might have meant to introduce type parameter", | |
| applicability = "maybe-incorrect", | |
| code = "{parameters}" | |
| )] | |
| pub(crate) struct SuggestIntroduceTypeParameter { | |
| #[primary_span] | |
| pub span: Span, | |
| pub parameters: String, | |
| } |