| use std::borrow::Cow; | |
| use rustc_errors::codes::*; | |
| use rustc_macros::{Diagnostic, Subdiagnostic}; | |
| use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol}; | |
| use rustc_structures::Limit; | |
| #[derive(Diagnostic)] | |
| #[diag("`#[cfg_attr]` does not expand to any attributes")] | |
| pub(crate) struct CfgAttrNoAttributes; | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "attempted to repeat an expression containing no syntax variables matched as repeating at this depth" | |
| )] | |
| pub(crate) struct NoSyntaxVarsExprRepeat { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub typo_repeatable: Option<VarTypoSuggestionRepeatable>, | |
| #[subdiagnostic] | |
| pub typo_unrepeatable: Option<VarTypoSuggestionUnrepeatable>, | |
| #[subdiagnostic] | |
| pub typo_unrepeatable_label: Option<VarTypoSuggestionUnrepeatableLabel>, | |
| #[subdiagnostic] | |
| pub var_no_typo: Option<VarNoTypo>, | |
| #[subdiagnostic] | |
| pub no_repeatable_var: Option<NoRepeatableVar>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "there's a macro metavariable with a similar name", | |
| applicability = "maybe-incorrect", | |
| style = "verbose" | |
| )] | |
| pub(crate) struct VarTypoSuggestionRepeatable { | |
| #[suggestion_part(code = "{name}")] | |
| pub span: Span, | |
| pub name: Symbol, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[label("argument not found")] | |
| pub(crate) struct VarTypoSuggestionUnrepeatable { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[label("this similarly named macro metavariable is unrepeatable")] | |
| pub(crate) struct VarTypoSuggestionUnrepeatableLabel { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[label("expected a repeatable metavariable: {$msg}")] | |
| pub(crate) struct VarNoTypo { | |
| #[primary_span] | |
| pub span: Span, | |
| pub msg: String, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[label( | |
| "this macro metavariable is not repeatable and there are no other repeatable metavariables" | |
| )] | |
| pub(crate) struct NoRepeatableVar { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("this must repeat at least once")] | |
| pub(crate) struct MustRepeatOnce { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`count` can not be placed inside the innermost repetition")] | |
| pub(crate) struct CountRepetitionMisplaced { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("variable `{$ident}` is still repeating at this depth")] | |
| pub(crate) struct MacroVarStillRepeating { | |
| #[primary_span] | |
| pub span: Span, | |
| pub ident: MacroRulesNormalizedIdent, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("variable `{$ident}` is still repeating at this depth")] | |
| pub(crate) struct MetaVarStillRepeatingLint { | |
| #[label("expected repetition")] | |
| pub label: Span, | |
| pub ident: MacroRulesNormalizedIdent, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("meta-variable repeats with different Kleene operator")] | |
| pub(crate) struct MetaVariableWrongOperator { | |
| #[label("expected repetition")] | |
| pub binder: Span, | |
| #[label("conflicting repetition")] | |
| pub occurrence: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("{$msg}")] | |
| pub(crate) struct MetaVarsDifSeqMatchers { | |
| #[primary_span] | |
| pub span: Span, | |
| pub msg: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unknown macro variable `{$name}`")] | |
| pub(crate) struct UnknownMacroVariable { | |
| pub name: MacroRulesNormalizedIdent, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("macros cannot have body stability attributes")] | |
| pub(crate) struct MacroBodyStability { | |
| #[primary_span] | |
| #[label("invalid body stability attribute")] | |
| pub span: Span, | |
| #[label("body stability attribute affects this macro")] | |
| pub head_span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("feature has been removed", code = E0557)] | |
| #[note("removed in {$removed_rustc_version}{$pull_note}")] | |
| pub(crate) struct FeatureRemoved<'a> { | |
| #[primary_span] | |
| #[label("feature has been removed")] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub reason: Option<FeatureRemovedReason<'a>>, | |
| pub removed_rustc_version: &'a str, | |
| pub pull_note: String, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[note("{$reason}")] | |
| pub(crate) struct FeatureRemovedReason<'a> { | |
| pub reason: &'a str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("the feature `{$name}` is not in the list of allowed features", code = E0725)] | |
| pub(crate) struct FeatureNotAllowed { | |
| #[primary_span] | |
| pub span: Span, | |
| pub name: Symbol, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("recursion limit reached while expanding `{$descr}`")] | |
| #[help( | |
| "consider increasing the recursion limit by adding a `#![recursion_limit = \"{$suggested_limit}\"]` attribute to your crate (`{$crate_name}`)" | |
| )] | |
| pub(crate) struct RecursionLimitReached { | |
| #[primary_span] | |
| pub span: Span, | |
| pub descr: String, | |
| pub suggested_limit: Limit, | |
| pub crate_name: Symbol, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("removing an expression is not supported in this position")] | |
| pub(crate) struct RemoveExprNotSupported { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("non-{$kind} macro in {$kind} position: {$name}")] | |
| pub(crate) struct WrongFragmentKind<'a> { | |
| #[primary_span] | |
| pub span: Span, | |
| pub kind: &'a str, | |
| pub name: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("key-value macro attributes are not supported")] | |
| pub(crate) struct UnsupportedKeyValue { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("macro expansion ignores {$descr} and any tokens following")] | |
| #[note("the usage of `{$macro_path}!` is likely invalid in {$kind_name} context")] | |
| pub(crate) struct IncompleteParse<'a> { | |
| #[primary_span] | |
| pub span: Span, | |
| pub descr: String, | |
| #[label("caused by the macro expansion here")] | |
| pub label_span: Span, | |
| pub macro_path: String, | |
| pub kind_name: &'a str, | |
| #[note("macros cannot expand to match arms")] | |
| pub expands_to_match_arm: bool, | |
| #[suggestion( | |
| "you might be missing a semicolon here", | |
| style = "verbose", | |
| code = ";", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub add_semicolon: Option<Span>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("removing {$descr} is not supported in this position")] | |
| pub(crate) struct RemoveNodeNotSupported { | |
| #[primary_span] | |
| pub span: Span, | |
| pub descr: &'static str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("circular modules: {$modules}")] | |
| pub(crate) struct ModuleCircular { | |
| #[primary_span] | |
| pub span: Span, | |
| pub modules: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("cannot declare a file module inside a block unless it has a path attribute")] | |
| #[note("file modules are usually placed outside of blocks, at the top level of the file")] | |
| pub(crate) struct ModuleInBlock { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub name: Option<ModuleInBlockName>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[help("maybe `use` the module `{$name}` instead of redeclaring it")] | |
| pub(crate) struct ModuleInBlockName { | |
| #[primary_span] | |
| pub span: Span, | |
| pub name: Ident, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("file not found for module `{$name}`", code = E0583)] | |
| #[help("to create the module `{$name}`, create file \"{$default_path}\" or \"{$secondary_path}\"")] | |
| #[note( | |
| "if there is a `mod {$name}` elsewhere in the crate already, import it with `use crate::...` instead" | |
| )] | |
| pub(crate) struct ModuleFileNotFound { | |
| #[primary_span] | |
| pub span: Span, | |
| pub name: Ident, | |
| pub default_path: String, | |
| pub secondary_path: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("file for module `{$name}` found at both \"{$default_path}\" and \"{$secondary_path}\"", code = E0761)] | |
| #[help("delete or rename one of them to remove the ambiguity")] | |
| pub(crate) struct ModuleMultipleCandidates { | |
| #[primary_span] | |
| pub span: Span, | |
| pub name: Ident, | |
| pub default_path: String, | |
| pub secondary_path: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("trace_macro")] | |
| pub(crate) struct TraceMacro { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("proc macro panicked")] | |
| pub(crate) struct ProcMacroPanicked { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub message: Option<ProcMacroPanickedHelp>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[help("message: {$message}")] | |
| pub(crate) struct ProcMacroPanickedHelp { | |
| pub message: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("proc-macro derive panicked")] | |
| pub(crate) struct ProcMacroDerivePanicked { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub message: Option<ProcMacroDerivePanickedHelp>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[help("message: {$message}")] | |
| pub(crate) struct ProcMacroDerivePanickedHelp { | |
| pub message: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("custom attribute panicked")] | |
| pub(crate) struct CustomAttributePanicked { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub message: Option<CustomAttributePanickedHelp>, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[help("message: {$message}")] | |
| pub(crate) struct CustomAttributePanickedHelp { | |
| pub message: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("proc-macro derive produced unparsable tokens")] | |
| pub(crate) struct ProcMacroDeriveTokens { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("duplicate matcher binding")] | |
| pub(crate) struct DuplicateMatcherBinding { | |
| #[primary_span] | |
| #[label("duplicate binding")] | |
| pub span: Span, | |
| #[label("previous binding")] | |
| pub prev: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("duplicate matcher binding")] | |
| pub(crate) struct DuplicateMatcherBindingLint { | |
| #[label("duplicate binding")] | |
| pub span: Span, | |
| #[label("previous binding")] | |
| pub prev: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("missing fragment specifier")] | |
| #[note("fragment specifiers must be provided")] | |
| #[help("{$valid}")] | |
| pub(crate) struct MissingFragmentSpecifier { | |
| #[primary_span] | |
| pub span: Span, | |
| #[suggestion( | |
| "try adding a specifier here", | |
| style = "verbose", | |
| code = ":spec", | |
| applicability = "maybe-incorrect" | |
| )] | |
| pub add_span: Span, | |
| pub valid: &'static str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("invalid fragment specifier `{$fragment}`")] | |
| #[help("{$help}")] | |
| pub(crate) struct InvalidFragmentSpecifier { | |
| #[primary_span] | |
| pub span: Span, | |
| pub fragment: Ident, | |
| pub help: &'static str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("expected `(` or `{\"{\"}`, found `{$token}`")] | |
| pub(crate) struct ExpectedParenOrBrace<'a> { | |
| #[primary_span] | |
| pub span: Span, | |
| pub token: Cow<'a, str>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("empty {$kind} delegation is not supported")] | |
| pub(crate) struct EmptyDelegationMac { | |
| #[primary_span] | |
| pub span: Span, | |
| pub kind: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("glob delegation is only supported in impls")] | |
| pub(crate) struct GlobDelegationOutsideImpls { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("the `crate_name` attribute is forbidden within a `cfg_attr` attribute")] | |
| pub(crate) struct CrateNameInCfgAttr { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("the `crate_type` attribute is forbidden within a `cfg_attr` attribute")] | |
| pub(crate) struct CrateTypeInCfgAttr { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("qualified path without a trait in glob delegation")] | |
| pub(crate) struct GlobDelegationTraitlessQpath { | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| pub(crate) use metavar_exprs::*; | |
| mod metavar_exprs { | |
| use super::*; | |
| #[derive(Diagnostic, Default)] | |
| #[diag("unexpected trailing tokens")] | |
| pub(crate) struct MveExtraTokens { | |
| #[primary_span] | |
| #[suggestion( | |
| "try removing {$extra_count -> | |
| [one] this token | |
| *[other] these tokens | |
| }", | |
| code = "", | |
| applicability = "machine-applicable" | |
| )] | |
| pub span: Span, | |
| #[label("for this metavariable expression")] | |
| pub ident_span: Span, | |
| pub extra_count: usize, | |
| // The rest is only used for specific diagnostics and can be default if neither | |
| // `note` is `Some`. | |
| #[note( | |
| "the `{$name}` metavariable expression takes {$min_or_exact_args -> | |
| [zero] no arguments | |
| [one] a single argument | |
| *[other] {$min_or_exact_args} arguments | |
| }" | |
| )] | |
| pub exact_args_note: Option<()>, | |
| #[note( | |
| "the `{$name}` metavariable expression takes between {$min_or_exact_args} and {$max_args} arguments" | |
| )] | |
| pub range_args_note: Option<()>, | |
| pub min_or_exact_args: usize, | |
| pub max_args: usize, | |
| pub name: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[note("metavariable expressions use function-like parentheses syntax")] | |
| #[diag("expected `(`")] | |
| pub(crate) struct MveMissingParen { | |
| #[primary_span] | |
| #[label("for this this metavariable expression")] | |
| pub ident_span: Span, | |
| #[label("unexpected token")] | |
| pub unexpected_span: Option<Span>, | |
| #[suggestion( | |
| "try adding parentheses", | |
| code = "( /* ... */ )", | |
| applicability = "has-placeholders" | |
| )] | |
| pub insert_span: Option<Span>, | |
| } | |
| #[derive(Diagnostic)] | |
| #[note("valid metavariable expressions are {$valid_expr_list}")] | |
| #[diag("unrecognized metavariable expression")] | |
| pub(crate) struct MveUnrecognizedExpr { | |
| #[primary_span] | |
| #[label("not a valid metavariable expression")] | |
| pub span: Span, | |
| pub valid_expr_list: &'static str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("variable `{$key}` is not recognized in meta-variable expression")] | |
| pub(crate) struct MveUnrecognizedVar { | |
| #[primary_span] | |
| pub span: Span, | |
| pub key: MacroRulesNormalizedIdent, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag(r#"`${"{"}concat(..){"}"}` is not generating a valid identifier"#)] | |
| pub(crate) struct ConcatInvalidIdent { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub reason: InvalidIdentReason, | |
| } | |
| #[derive(Subdiagnostic)] | |
| pub(crate) enum InvalidIdentReason { | |
| #[note(r#"this `${"{"}concat(..){"}"}` invocation generated an empty ident"#)] | |
| Empty, | |
| #[note(r#"this `${"{"}concat(..){"}"}` invocation generated `{$symbol}`, but {$start} is neither '_' nor XID_Start"#)] | |
| #[note( | |
| "see <https://doc.rust-lang.org/reference/identifiers.html> for the definition of valid identifiers" | |
| )] | |
| InvalidStart { symbol: Symbol, start: char }, | |
| #[note(r#"this `${"{"}concat(..){"}"}` invocation generated `{$symbol}`, but {$not_continue} is not XID_Continue"#)] | |
| #[note( | |
| "see <https://doc.rust-lang.org/reference/identifiers.html> for the definition of valid identifiers" | |
| )] | |
| InvalidContinue { symbol: Symbol, not_continue: char }, | |
| } | |
| impl InvalidIdentReason { | |
| pub(crate) fn new(symbol: Symbol) -> Self { | |
| let mut chars = symbol.as_str().chars(); | |
| if let Some(start) = chars.next() { | |
| if rustc_lexer::is_id_start(start) { | |
| let not_continue = chars | |
| .find(|c| !rustc_lexer::is_id_continue(*c)) | |
| .expect("InvalidIdentReason: cannot find invalid ident reason"); | |
| InvalidIdentReason::InvalidContinue { symbol, not_continue } | |
| } else { | |
| InvalidIdentReason::InvalidStart { symbol, start } | |
| } | |
| } else { | |
| InvalidIdentReason::Empty | |
| } | |
| } | |
| } | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`{$rule_kw}` rule argument matchers require parentheses")] | |
| pub(crate) struct MacroArgsBadDelim { | |
| #[primary_span] | |
| pub span: Span, | |
| #[subdiagnostic] | |
| pub sugg: MacroArgsBadDelimSugg, | |
| pub rule_kw: Symbol, | |
| } | |
| #[derive(Subdiagnostic)] | |
| #[multipart_suggestion( | |
| "the delimiters should be `(` and `)`", | |
| applicability = "machine-applicable" | |
| )] | |
| pub(crate) struct MacroArgsBadDelimSugg { | |
| #[suggestion_part(code = "(")] | |
| pub open: Span, | |
| #[suggestion_part(code = ")")] | |
| pub close: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unused doc comment")] | |
| #[help( | |
| "to document an item produced by a macro, the macro must produce the documentation as part of its expansion" | |
| )] | |
| pub(crate) struct MacroCallUnusedDocComment { | |
| #[label("rustdoc does not generate documentation for macro invocations")] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro" | |
| )] | |
| pub(crate) struct OrPatternsBackCompat { | |
| #[suggestion( | |
| "use pat_param to preserve semantics", | |
| code = "{suggestion}", | |
| applicability = "machine-applicable" | |
| )] | |
| pub span: Span, | |
| pub suggestion: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("trailing semicolon in macro used in expression position")] | |
| pub(crate) struct TrailingMacro { | |
| #[note("macro invocations at the end of a block are treated as expressions")] | |
| #[note( | |
| "to ignore the value produced by the macro, add a semicolon after the invocation of `{$name}`" | |
| )] | |
| pub is_trailing: bool, | |
| pub name: Ident, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unused attribute `{$attr_name}`")] | |
| pub(crate) struct UnusedBuiltinAttribute { | |
| #[note( | |
| "the built-in attribute `{$attr_name}` will be ignored, since it's applied to the macro invocation `{$macro_name}`" | |
| )] | |
| pub invoc_span: Span, | |
| pub attr_name: Symbol, | |
| pub macro_name: String, | |
| #[suggestion( | |
| "remove the attribute", | |
| code = "", | |
| applicability = "machine-applicable", | |
| style = "tool-only" | |
| )] | |
| pub attr_span: Span, | |
| } |