4472 lines
121 KiB
Rust
4472 lines
121 KiB
Rust
// ignore-tidy-filelength
|
|
|
|
use std::borrow::Cow;
|
|
use std::path::PathBuf;
|
|
|
|
use rustc_ast::token::{self, InvisibleOrigin, MetaVarKind, Token};
|
|
use rustc_ast::util::parser::ExprPrecedence;
|
|
use rustc_ast::{Path, Visibility};
|
|
use rustc_errors::codes::*;
|
|
use rustc_errors::{
|
|
Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg,
|
|
Level, Subdiagnostic, SuggestionStyle, inline_fluent,
|
|
};
|
|
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
|
use rustc_session::errors::ExprParenthesesNeeded;
|
|
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: Token,
|
|
#[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: 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: Path,
|
|
#[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: Path,
|
|
#[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: Token,
|
|
#[subdiagnostic]
|
|
pub suggestion: ExprParenthesesNeeded,
|
|
}
|
|
|
|
#[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,
|
|
pub r#type: Path,
|
|
#[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 {
|
|
#[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 {
|
|
#[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 `..=`")]
|
|
pub span: Span,
|
|
#[suggestion(
|
|
"add a space between the pattern and `=>`",
|
|
style = "verbose",
|
|
code = " ",
|
|
applicability = "machine-applicable"
|
|
)]
|
|
pub after_pat: 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]
|
|
pub span: Span,
|
|
#[suggestion(
|
|
"use `..` instead",
|
|
code = "",
|
|
applicability = "machine-applicable",
|
|
style = "verbose"
|
|
)]
|
|
pub suggestion: 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,
|
|
},
|
|
#[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("<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("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) => {
|
|
inline_fluent!("expected identifier, found reserved identifier `{$token}`")
|
|
}
|
|
Some(TokenDescription::Keyword) => {
|
|
inline_fluent!("expected identifier, found keyword `{$token}`")
|
|
}
|
|
Some(TokenDescription::ReservedKeyword) => {
|
|
inline_fluent!("expected identifier, found reserved keyword `{$token}`")
|
|
}
|
|
Some(TokenDescription::DocComment) => {
|
|
inline_fluent!("expected identifier, found doc comment `{$token}`")
|
|
}
|
|
Some(TokenDescription::MetaVar(_)) => {
|
|
add_token = false;
|
|
inline_fluent!("expected identifier, found metavariable")
|
|
}
|
|
None => inline_fluent!("expected identifier, found `{$token}`"),
|
|
},
|
|
);
|
|
diag.span(self.span);
|
|
if add_token {
|
|
diag.arg("token", 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) => {
|
|
inline_fluent!("expected `;`, found reserved identifier `{$token}`")
|
|
}
|
|
Some(TokenDescription::Keyword) => {
|
|
inline_fluent!("expected `;`, found keyword `{$token}`")
|
|
}
|
|
Some(TokenDescription::ReservedKeyword) => {
|
|
inline_fluent!("expected `;`, found reserved keyword `{$token}`")
|
|
}
|
|
Some(TokenDescription::DocComment) => {
|
|
inline_fluent!("expected `;`, found doc comment `{$token}`")
|
|
}
|
|
Some(TokenDescription::MetaVar(_)) => {
|
|
add_token = false;
|
|
inline_fluent!("expected `;`, found metavariable")
|
|
}
|
|
None => inline_fluent!("expected `;`, found `{$token}`"),
|
|
},
|
|
);
|
|
diag.span(self.span);
|
|
if add_token {
|
|
diag.arg("token", self.token);
|
|
}
|
|
|
|
if let Some(unexpected_token_label) = self.unexpected_token_label {
|
|
diag.span_label(unexpected_token_label, inline_fluent!("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 methods without bodies", 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,
|
|
}
|
|
|
|
#[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, inline_fluent!("`Fn` bounds require arguments in parentheses"));
|
|
diag.span_suggestion_short(
|
|
self.span.shrink_to_hi(),
|
|
inline_fluent!("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 named parameters")]
|
|
pub(crate) struct FnPathFoundNamedParams {
|
|
#[primary_span]
|
|
#[suggestion("remove the parameter name", applicability = "machine-applicable", code = "")]
|
|
pub named_param_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: Visibility,
|
|
}
|
|
|
|
#[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)]
|
|
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("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: Token,
|
|
},
|
|
#[diag("expected `where`, `{\"{\"}`, `(`, or `;` after struct name, found keyword `{$token}`")]
|
|
Keyword {
|
|
#[primary_span]
|
|
#[label("expected `where`, `{\"{\"}`, `(`, or `;` after struct name")]
|
|
span: Span,
|
|
token: Token,
|
|
},
|
|
#[diag(
|
|
"expected `where`, `{\"{\"}`, `(`, or `;` after struct name, found reserved keyword `{$token}`"
|
|
)]
|
|
ReservedKeyword {
|
|
#[primary_span]
|
|
#[label("expected `where`, `{\"{\"}`, `(`, or `;` after struct name")]
|
|
span: Span,
|
|
token: Token,
|
|
},
|
|
#[diag(
|
|
"expected `where`, `{\"{\"}`, `(`, or `;` after struct name, found doc comment `{$token}`"
|
|
)]
|
|
DocComment {
|
|
#[primary_span]
|
|
#[label("expected `where`, `{\"{\"}`, `(`, or `;` after struct name")]
|
|
span: Span,
|
|
token: Token,
|
|
},
|
|
#[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: Token,
|
|
},
|
|
}
|
|
|
|
impl UnexpectedTokenAfterStructName {
|
|
pub(crate) fn new(span: Span, token: Token) -> Self {
|
|
match TokenDescription::from_token(&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: Token,
|
|
},
|
|
#[diag("expected a lifetime, found `{$token}`")]
|
|
Lifetime {
|
|
#[primary_span]
|
|
span: Span,
|
|
token: Token,
|
|
},
|
|
}
|
|
|
|
#[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>,
|
|
#[subdiagnostic]
|
|
pub null: Option<UnknownTokenNull>,
|
|
#[subdiagnostic]
|
|
pub repeat: Option<UnknownTokenRepeat>,
|
|
#[subdiagnostic]
|
|
pub invisible: Option<InvisibleCharacter>,
|
|
}
|
|
|
|
#[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(Subdiagnostic)]
|
|
#[help("invisible characters like '{$escaped}' are not usually visible in text editors")]
|
|
pub(crate) struct InvisibleCharacter;
|
|
|
|
#[derive(Subdiagnostic)]
|
|
#[help(
|
|
"source files must contain UTF-8 encoded text, unexpected null bytes might occur when a different encoding is used"
|
|
)]
|
|
pub(crate) struct UnknownTokenNull;
|
|
|
|
#[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,
|
|
}
|
|
|
|
#[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: Token,
|
|
#[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,
|
|
/// The unexpected expr's precedence (used in match arm guard suggestions).
|
|
pub expr_precedence: ExprPrecedence,
|
|
}
|
|
|
|
#[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(LintDiagnostic)]
|
|
#[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)> },
|
|
}
|
|
|
|
// 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(
|
|
inline_fluent!("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(
|
|
inline_fluent!("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 } => {
|
|
// 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(inline_fluent!(
|
|
"if their presence wasn't intentional, you can remove them"
|
|
));
|
|
diag.note(inline_fluent!("if you want to keep them but make them visible in your source code, you can escape them: {$escaped}"));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(LintDiagnostic)]
|
|
#[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,
|
|
}
|
|
}
|
|
}
|