From a8265ed00020757d6a1e5446936382d16c650228 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Sun, 14 Apr 2024 11:38:27 +0000 Subject: [PATCH] rustc_expand: make mbe translatable --- compiler/rustc_expand/messages.ftl | 115 +++++- compiler/rustc_expand/src/errors.rs | 345 +++++++++++++++++- compiler/rustc_expand/src/lib.rs | 2 - compiler/rustc_expand/src/mbe.rs | 2 + compiler/rustc_expand/src/mbe/diagnostics.rs | 84 ++--- compiler/rustc_expand/src/mbe/macro_check.rs | 13 +- compiler/rustc_expand/src/mbe/macro_parser.rs | 87 +++-- compiler/rustc_expand/src/mbe/macro_rules.rs | 135 +++---- compiler/rustc_expand/src/mbe/metavar_expr.rs | 76 ++-- compiler/rustc_expand/src/mbe/quoted.rs | 85 ++--- compiler/rustc_expand/src/mbe/transcribe.rs | 75 ++-- .../unused-macro-with-follow-violation.stderr | 2 +- tests/ui/macros/macro-follow.stderr | 170 ++++----- .../macros/macro-followed-by-seq-bad.stderr | 4 +- .../macros/macro-input-future-proofing.stderr | 18 +- ...-pat-pattern-followed-by-or-in-2021.stderr | 6 +- ...acro-pat2021-pattern-followed-by-or.stderr | 6 +- .../syntax-errors.stderr | 4 +- tests/ui/macros/same-sequence-span.stderr | 8 +- .../type/pattern_types/macros.active.stderr | 2 +- .../ui/type/pattern_types/macros.gated.stderr | 2 +- 21 files changed, 831 insertions(+), 410 deletions(-) diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl index 3bb1b5dea41c6..de4a1653ce82d 100644 --- a/compiler/rustc_expand/messages.ftl +++ b/compiler/rustc_expand/messages.ftl @@ -24,9 +24,17 @@ expand_cannot_be_name_of_macro = expand_collapse_debuginfo_illegal = illegal value for attribute #[collapse_debuginfo(no|external|yes)] +expand_concat_generated_invalid_ident = `{"${concat(..)}"}` is not generating a valid identifier + +expand_concat_raw_ident = `{"${concat(..)}"}` currently does not support raw identifiers + +expand_concat_too_few_args = `concat` must have at least two elements + expand_count_repetition_misplaced = `count` can not be placed inside the inner-most repetition +expand_count_with_comma_no_index = `count` followed by a comma must have an associated index indicating its depth + expand_custom_attribute_cannot_be_applied = custom attributes cannot be applied to {$kind -> [statement] statements @@ -37,6 +45,13 @@ expand_custom_attribute_panicked = custom attribute panicked .help = message: {$message} +expand_doc_comments_ignored_in_matcher_position = doc comments are ignored in matcher position + +expand_dollar_or_metavar_in_lhs = unexpected token: {$token} + .note = `$$` and meta-variable expressions are not allowed inside macro parameter definitions + +expand_duplicate_binding_name = duplicated bind name: {$bind} + expand_duplicate_matcher_binding = duplicate matcher binding .label = duplicate binding .label2 = previous binding @@ -44,15 +59,23 @@ expand_duplicate_matcher_binding = duplicate matcher binding expand_empty_delegation_mac = empty {$kind} delegation is not supported +expand_expected_comma = expected comma + +expand_expected_identifier = expected identifier, found `{$found}` + expand_expected_paren_or_brace = expected `(` or `{"{"}`, found `{$token}` +expand_expected_repetition_operator = expected one of: `*`, `+`, or `?` + expand_explain_doc_comment_inner = inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match expand_explain_doc_comment_outer = outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match +expand_expr_2021_unstable = fragment specifier `expr_2021` is unstable + expand_expr_repeat_no_syntax_vars = attempted to repeat an expression containing no syntax variables matched as repeating at this depth @@ -86,9 +109,30 @@ expand_invalid_cfg_no_parens = `cfg` is not followed by parentheses expand_invalid_cfg_no_predicate = `cfg` predicate is not specified expand_invalid_cfg_predicate_literal = `cfg` predicate key cannot be a literal +expand_invalid_concat_arg_type = metavariables of {"`${concat(..)}`"} must be of type `ident`, `literal` or `tt` + .note = currently only string literals are supported + +expand_invalid_follow = `${$name}:{$kind}` {$only_option -> + [true] is + *[false] may be + } followed by `{$next}`, which is not allowed for `{$kind}` fragments + .label = not allowed after `{$kind}` fragments + .suggestion = try a `pat_param` fragment specifier instead + .note = {$num_possible -> + [one] only {$possible} is allowed after `{$kind}` fragments + *[other] allowed there are: {$possible} + } + expand_invalid_fragment_specifier = invalid fragment specifier `{$fragment}` - .help = {$help} + .help_expr_2021 = fragment specifier `expr_2021` requires Rust 2021 or later + +expand_label_conflicting_repetition = conflicting repetition + +expand_label_error_while_parsing_argument = while parsing argument for this `{$kind}` macro fragment + +expand_label_expected_repetition = expected repetition +expand_label_previous_declaration = previous declaration expand_macro_body_stability = macros cannot have body stability attributes @@ -102,19 +146,51 @@ expand_macro_const_stability = expand_macro_expands_to_match_arm = macros cannot expand to match arms +expand_macro_rhs_must_be_delimited = macro rhs must be delimited + expand_malformed_feature_attribute = malformed `feature` attribute input .expected = expected just one word -expand_meta_var_dif_seq_matchers = {$msg} +expand_match_failure_missing_tokens = missing tokens in macro arguments +expand_match_failure_unexpected_token = no rules expected this token in macro call + +expand_meta_var_dif_seq_matchers = + meta-variable `{$var1_id}` repeats {$var1_len} {$var1_len -> + [one] time + *[count] times + }, but `{$var2_id}` repeats {$var2_len} {$var2_len -> + [one] time + *[count] times + } + +expand_meta_var_expr_concat_unstable = the `concat` meta-variable expression is unstable + +expand_meta_var_expr_depth_not_literal = meta-variable expression depth must be a literal + +expand_meta_var_expr_depth_suffixed = only unsuffixed integer literals are supported in meta-variable expressions + +expand_meta_var_expr_expected_identifier = expected identifier, found `{$found}` + .suggestion = try removing `{$found}` + +expand_meta_var_expr_needs_parens = meta-variable expression parameter must be wrapped in parentheses + +expand_meta_var_expr_out_of_bounds = {$max -> + [0] meta-variable expression `{$ty}` with depth parameter must be called inside of a macro repetition + *[other] depth parameter of meta-variable expression `{$ty}` must be less than {$max} + } + +expand_meta_var_expr_unexpected_token = unexpected token: {$tt} + .note = meta-variable expression must not have trailing tokens expand_meta_var_expr_unrecognized_var = variable `{$key}` is not recognized in meta-variable expression +expand_meta_var_expr_unstable = meta-variable expressions are unstable + expand_missing_fragment_specifier = missing fragment specifier .note = fragment specifiers must be specified in the 2024 edition .suggestion_add_fragspec = try adding a specifier here - .valid = {$valid} expand_module_circular = circular modules: {$modules} @@ -132,9 +208,22 @@ expand_module_multiple_candidates = file for module `{$name}` found at both "{$default_path}" and "{$secondary_path}" .help = delete or rename one of them to remove the ambiguity +expand_multiple_parsing_options = + local ambiguity when calling macro `{$macro_name}`: multiple parsing options: built-in NTs {$nts}{$n -> + [0] . + [one] {""} or {$n} other option + *[other] {""} or {$n} other options + } + +expand_multiple_successful_parses = ambiguity: multiple successful parses + +expand_multiple_transparency_attrs = multiple macro transparency attributes + expand_must_repeat_once = this must repeat at least once +expand_nested_meta_var_expr_without_dollar = meta-variables within meta-variable expressions must be referenced using a dollar sign + expand_non_inline_modules_in_proc_macro_input_are_unstable = non-inline modules in proc macro input are unstable @@ -144,6 +233,10 @@ expand_not_a_meta_item = expand_only_one_word = must only be one word +expand_parse_failure_expected_token = expected `{$expected}`, found `{$found}` +expand_parse_failure_unexpected_eof = unexpected end of macro invocation +expand_parse_failure_unexpected_token = no rules expected the token `{$found}` + expand_proc_macro_back_compat = using an old version of `{$crate_name}` .note = older versions of the `{$crate_name}` crate no longer compile; please update to `{$crate_name}` v{$fixed_version}, or switch to one of the `{$crate_name}` alternatives @@ -158,6 +251,8 @@ expand_proc_macro_panicked = proc macro panicked .help = message: {$message} +expand_question_mark_with_separator = the `?` macro repetition operator does not take a separator + expand_recursion_limit_reached = 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}`) @@ -168,14 +263,28 @@ expand_remove_expr_not_supported = expand_remove_node_not_supported = removing {$descr} is not supported in this position +expand_repetition_matches_empty_token_tree = repetition matches empty token tree + expand_resolve_relative_path = cannot resolve relative path in non-file source `{$path}` expand_trace_macro = trace_macro +expand_unbalanced_delims_around_matcher = invalid macro matcher; matchers must be contained in balanced delimiters + +expand_unknown_macro_transparency = unknown macro transparency: `{$value}` + +expand_unrecognized_meta_var_expr = unrecognized meta-variable expression + .help = supported expressions are count, ignore, index and len + +expand_unsupported_concat_elem = expected identifier or string literal + expand_unsupported_key_value = key-value macro attributes are not supported +expand_valid_fragment_names_2021 = valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis` +expand_valid_fragment_names_other = valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis` + expand_var_still_repeating = variable `{$ident}` is still repeating at this depth diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index 0a4a32f71b1f8..8e11231cca18e 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -1,8 +1,10 @@ use std::borrow::Cow; use rustc_ast::ast; +use rustc_ast::token::{NonterminalKind, Token}; +use rustc_ast::tokenstream::TokenTree; use rustc_errors::codes::*; -use rustc_errors::IntoDiagArg; +use rustc_errors::{DiagArgValue, IntoDiagArg, MultiSpan}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_session::errors::FeatureGateSubdiagnostic; use rustc_session::Limit; @@ -51,7 +53,10 @@ pub(crate) struct VarStillRepeating { pub(crate) struct MetaVarsDifSeqMatchers { #[primary_span] pub span: Span, - pub msg: String, + pub var1_id: String, + pub var1_len: usize, + pub var2_id: String, + pub var2_len: usize, } #[derive(Diagnostic)] @@ -421,10 +426,17 @@ pub struct DuplicateMatcherBinding { pub prev: Span, } +#[derive(Subdiagnostic)] +pub enum InvalidFragmentSpecifierValidNames { + #[help(expand_valid_fragment_names_2021)] + Edition2021, + #[help(expand_valid_fragment_names_other)] + Other, +} + #[derive(Diagnostic)] #[diag(expand_missing_fragment_specifier)] #[note] -#[help(expand_valid)] pub struct MissingFragmentSpecifier { #[primary_span] pub span: Span, @@ -435,17 +447,20 @@ pub struct MissingFragmentSpecifier { applicability = "maybe-incorrect" )] pub add_span: Span, - pub valid: &'static str, + #[subdiagnostic] + pub valid: InvalidFragmentSpecifierValidNames, } #[derive(Diagnostic)] #[diag(expand_invalid_fragment_specifier)] -#[help] pub struct InvalidFragmentSpecifier { #[primary_span] pub span: Span, + #[help(expand_help_expr_2021)] + pub help_expr_2021: bool, + #[subdiagnostic] + pub help_valid_names: InvalidFragmentSpecifierValidNames, pub fragment: Ident, - pub help: String, } #[derive(Diagnostic)] @@ -522,3 +537,321 @@ pub struct NonInlineModuleInProcMacroUnstable { #[subdiagnostic] pub subdiag: FeatureGateSubdiagnostic, } + +#[derive(Subdiagnostic)] +#[label(expand_label_error_while_parsing_argument)] +pub struct NoteParseErrorInMacroArgument { + #[primary_span] + pub span: Span, + pub kind: NonterminalKind, +} + +#[derive(Diagnostic)] +#[diag(expand_meta_var_expr_needs_parens)] +pub struct MetaVarExprParamNeedsParens { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_unsupported_concat_elem)] +pub struct UnsupportedConcatElem { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_concat_raw_ident)] +pub struct ConcatRawIdent { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_expected_comma)] +pub struct ExpectedComma { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_concat_too_few_args)] +pub struct ConcatTooFewArgs { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_unrecognized_meta_var_expr)] +#[help] +pub struct UnrecognizedMetaVarExpr { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_count_with_comma_no_index)] +pub struct CountWithCommaNoIndex { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_nested_meta_var_expr_without_dollar)] +pub struct NestedMetaVarExprWithoutDollar { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_meta_var_expr_depth_not_literal)] +pub struct MetaVarExprDepthNotLiteral { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_meta_var_expr_depth_suffixed)] +pub struct MetaVarExprDepthSuffixed { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_meta_var_expr_unexpected_token)] +pub struct MetaVarExprUnexpectedToken { + #[primary_span] + #[note] + pub span: Span, + pub tt: TokenTree, +} + +#[derive(Diagnostic)] +#[diag(expand_meta_var_expr_expected_identifier)] +pub struct MetaVarExprExpectedIdentifier { + #[primary_span] + #[suggestion(code = "", applicability = "maybe-incorrect")] + pub span: Span, + pub found: Token, +} + +#[derive(Diagnostic)] +#[diag(expand_expected_identifier)] +pub struct ExpectedIdentifier { + #[primary_span] + pub span: Span, + pub found: Token, +} + +#[derive(Diagnostic)] +#[diag(expand_question_mark_with_separator)] +pub struct QuestionMarkWithSeparator { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_expected_repetition_operator)] +pub struct ExpectedRepetitionOperator { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_dollar_or_metavar_in_lhs)] +pub struct DollarOrMetavarInLhs { + #[primary_span] + #[note] + pub span: Span, + pub token: Token, +} + +#[derive(Diagnostic)] +#[diag(expand_meta_var_expr_out_of_bounds)] +pub struct MetaVarExprOutOfBounds { + #[primary_span] + pub span: Span, + pub ty: String, + pub max: usize, +} + +#[derive(Diagnostic)] +#[diag(expand_concat_generated_invalid_ident)] +pub struct ConcatGeneratedInvalidIdent { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_invalid_concat_arg_type)] +#[note] +pub struct InvalidConcatArgType { + #[primary_span] + pub span: Span, +} + +#[derive(Subdiagnostic)] +pub enum MatchFailureLabel { + #[label(expand_match_failure_missing_tokens)] + MissingTokens(#[primary_span] Span), + #[label(expand_match_failure_unexpected_token)] + UnexpectedToken(#[primary_span] Span), +} + +#[derive(Subdiagnostic)] +pub enum ExplainDocComment { + #[label(expand_explain_doc_comment_inner)] + Inner { + #[primary_span] + span: Span, + }, + #[label(expand_explain_doc_comment_outer)] + Outer { + #[primary_span] + span: Span, + }, +} + +#[derive(Subdiagnostic)] +pub struct ParseFailureSubdiags { + #[subdiagnostic] + pub failure_label: MatchFailureLabel, + #[subdiagnostic] + pub doc_comment: Option, +} + +#[derive(Diagnostic)] +pub enum ParseFailure { + #[diag(expand_parse_failure_expected_token)] + ExpectedToken { + #[primary_span] + span: Span, + expected: Token, + found: Token, + #[subdiagnostic] + subdiags: ParseFailureSubdiags, + }, + #[diag(expand_parse_failure_unexpected_eof)] + UnexpectedEof { + #[primary_span] + span: Span, + #[subdiagnostic] + subdiags: ParseFailureSubdiags, + }, + #[diag(expand_parse_failure_unexpected_token)] + UnexpectedToken { + #[primary_span] + span: Span, + found: Token, + #[subdiagnostic] + subdiags: ParseFailureSubdiags, + }, +} + +#[derive(Diagnostic)] +#[diag(expand_unknown_macro_transparency)] +pub struct UnknownMacroTransparency { + #[primary_span] + pub span: Span, + pub value: Symbol, +} + +#[derive(Diagnostic)] +#[diag(expand_multiple_transparency_attrs)] +pub struct MultipleTransparencyAttrs { + #[primary_span] + pub spans: MultiSpan, +} + +#[derive(Diagnostic)] +#[diag(expand_unbalanced_delims_around_matcher)] +pub struct UnbalancedDelimsAroundMatcher { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_doc_comments_ignored_in_matcher_position)] +pub struct DocCommentsIgnoredInMatcherPosition { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_repetition_matches_empty_token_tree)] +pub struct RepetitionMatchesEmptyTokenTree { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_macro_rhs_must_be_delimited)] +pub struct MacroRhsMustBeDelimited { + #[primary_span] + pub span: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion(expand_suggestion, code = "{suggestion}", applicability = "maybe-incorrect")] +pub struct InvalidFollowSuggestion { + #[primary_span] + pub span: Span, + pub suggestion: String, +} + +#[derive(Subdiagnostic)] +#[note(expand_note)] +pub struct InvalidFollowNote { + pub num_possible: usize, + pub possible: DiagArgValue, +} + +#[derive(Diagnostic)] +#[diag(expand_invalid_follow)] +pub struct InvalidFollow { + #[primary_span] + #[label] + pub span: Span, + pub name: Ident, + pub kind: NonterminalKind, + pub next: String, + pub only_option: bool, + + #[subdiagnostic] + pub suggestion: Option, + #[subdiagnostic] + pub note_allowed: Option, +} + +// FIXME: unify this with MissingFragmentSpecifier +#[derive(Diagnostic)] +#[diag(expand_missing_fragment_specifier)] +pub struct MissingFragmentSpecifierThin { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_multiple_successful_parses)] +pub struct MultipleSuccessfulParses { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_duplicate_binding_name)] +pub struct DuplicateBindingName { + #[primary_span] + pub span: Span, + pub bind: Ident, +} + +#[derive(Diagnostic)] +#[diag(expand_multiple_parsing_options)] +pub struct MultipleParsingOptions { + #[primary_span] + pub span: Span, + pub macro_name: Ident, + pub n: usize, + pub nts: DiagArgValue, +} diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 4222c9fe90616..1ba814b09fedb 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -19,8 +19,6 @@ extern crate proc_macro as pm; mod build; mod errors; -// FIXME(Nilstrieb) Translate macro_rules diagnostics -#[allow(rustc::untranslatable_diagnostic)] mod mbe; mod placeholders; mod proc_macro_server; diff --git a/compiler/rustc_expand/src/mbe.rs b/compiler/rustc_expand/src/mbe.rs index 08d4a03945489..8b0683394c018 100644 --- a/compiler/rustc_expand/src/mbe.rs +++ b/compiler/rustc_expand/src/mbe.rs @@ -3,6 +3,8 @@ //! why we call this module `mbe`. For external documentation, prefer the //! official terminology: "declarative macros". +// FIXME(Noratrieb) Translate diagnostics +#[allow(rustc::untranslatable_diagnostic)] pub(crate) mod diagnostics; pub(crate) mod macro_rules; diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index 628c6bfeb7932..7377c26cc8e95 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -2,9 +2,7 @@ use std::borrow::Cow; use rustc_ast::token::{self, Token, TokenKind}; use rustc_ast::tokenstream::TokenStream; -use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, Diag, DiagCtxtHandle, DiagMessage}; -use rustc_macros::Subdiagnostic; use rustc_parse::parser::{Parser, Recovery}; use rustc_session::parse::ParseSess; use rustc_span::source_map::SourceMap; @@ -12,7 +10,8 @@ use rustc_span::symbol::Ident; use rustc_span::{ErrorGuaranteed, Span}; use tracing::debug; -use super::macro_rules::{parser_from_cx, NoopTracker}; +use super::macro_rules::{parser_from_cx, MatchFailureReason, NoopTracker}; +use crate::errors::{self, ParseFailureSubdiags}; use crate::expand::{parse_ast_fragment, AstFragmentKind}; use crate::mbe::macro_parser::ParseResult::*; use crate::mbe::macro_parser::{MatcherLoc, NamedParseResult, TtParser}; @@ -53,14 +52,17 @@ pub(super) fn failed_to_match_macro( let span = token.span.substitute_dummy(sp); - let mut err = psess.dcx().struct_span_err(span, parse_failure_msg(&token, None)); - err.span_label(span, label); + let mut err = psess.dcx().create_err(parse_failure_err( + span, + psess.source_map(), + label, + token.clone(), + None, + )); if !def_span.is_dummy() && !psess.source_map().is_imported(def_span) { err.span_label(psess.source_map().guess_head_span(def_span), "when calling this macro"); } - annotate_doc_comment(&mut err, psess.source_map(), span); - if let Some(span) = remaining_matcher.span() { err.span_note(span, format!("while trying to match {remaining_matcher}")); } else { @@ -118,7 +120,7 @@ struct CollectTrackerAndEmitter<'dcx, 'matcher> { struct BestFailure { token: Token, position_in_tokenstream: u32, - msg: &'static str, + msg: MatchFailureReason, remaining_matcher: MatcherLoc, } @@ -129,9 +131,9 @@ impl BestFailure { } impl<'dcx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'dcx, 'matcher> { - type Failure = (Token, u32, &'static str); + type Failure = (Token, u32, MatchFailureReason); - fn build_failure(tok: Token, position: u32, msg: &'static str) -> Self::Failure { + fn build_failure(tok: Token, position: u32, msg: MatchFailureReason) -> Self::Failure { (tok, position, msg) } @@ -164,7 +166,7 @@ impl<'dcx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'dcx, 'match self.best_failure = Some(BestFailure { token: token.clone(), position_in_tokenstream: *approx_position, - msg, + msg: *msg, remaining_matcher: self .remaining_matcher .expect("must have collected matcher already") @@ -174,7 +176,7 @@ impl<'dcx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'dcx, 'match } Error(err_sp, msg) => { let span = err_sp.substitute_dummy(self.root_span); - let guar = self.dcx.span_err(span, msg.clone()); + let guar = msg.emit_err(self.dcx, span); self.result = Some((span, guar)); } ErrorReported(guar) => self.result = Some((self.root_span, *guar)), @@ -208,9 +210,9 @@ impl<'matcher> FailureForwarder<'matcher> { } impl<'matcher> Tracker<'matcher> for FailureForwarder<'matcher> { - type Failure = (Token, u32, &'static str); + type Failure = (Token, u32, MatchFailureReason); - fn build_failure(tok: Token, position: u32, msg: &'static str) -> Self::Failure { + fn build_failure(tok: Token, position: u32, msg: MatchFailureReason) -> Self::Failure { (tok, position, msg) } @@ -307,45 +309,35 @@ pub(crate) fn annotate_err_with_kind(err: &mut Diag<'_>, kind: AstFragmentKind, }; } -#[derive(Subdiagnostic)] -enum ExplainDocComment { - #[label(expand_explain_doc_comment_inner)] - Inner { - #[primary_span] - span: Span, - }, - #[label(expand_explain_doc_comment_outer)] - Outer { - #[primary_span] - span: Span, - }, -} - -pub(super) fn annotate_doc_comment(err: &mut Diag<'_>, sm: &SourceMap, span: Span) { - if let Ok(src) = sm.span_to_snippet(span) { +/// Generates an appropriate parsing failure message. For EOF, this is "unexpected end...". For +/// other tokens, this is "unexpected token...". +pub(super) fn parse_failure_err( + span: Span, + sm: &SourceMap, + reason: MatchFailureReason, + tok: Token, + expected_token: Option, +) -> errors::ParseFailure { + let failure_label = reason.into_label(span); + let doc_comment = if let Ok(src) = sm.span_to_snippet(span) { if src.starts_with("///") || src.starts_with("/**") { - err.subdiagnostic(ExplainDocComment::Outer { span }); + Some(errors::ExplainDocComment::Outer { span }) } else if src.starts_with("//!") || src.starts_with("/*!") { - err.subdiagnostic(ExplainDocComment::Inner { span }); + Some(errors::ExplainDocComment::Inner { span }) + } else { + None } - } -} + } else { + None + }; + let subdiags = ParseFailureSubdiags { failure_label, doc_comment }; -/// Generates an appropriate parsing failure message. For EOF, this is "unexpected end...". For -/// other tokens, this is "unexpected token...". -pub(super) fn parse_failure_msg(tok: &Token, expected_token: Option<&Token>) -> Cow<'static, str> { if let Some(expected_token) = expected_token { - Cow::from(format!( - "expected `{}`, found `{}`", - pprust::token_to_string(expected_token), - pprust::token_to_string(tok), - )) + errors::ParseFailure::ExpectedToken { span, expected: expected_token, found: tok, subdiags } } else { match tok.kind { - token::Eof => Cow::from("unexpected end of macro invocation"), - _ => { - Cow::from(format!("no rules expected the token `{}`", pprust::token_to_string(tok))) - } + token::Eof => errors::ParseFailure::UnexpectedEof { span, subdiags }, + _ => errors::ParseFailure::UnexpectedToken { span, found: tok, subdiags }, } } } diff --git a/compiler/rustc_expand/src/mbe/macro_check.rs b/compiler/rustc_expand/src/mbe/macro_check.rs index 68eeba6f415d5..de98608fab942 100644 --- a/compiler/rustc_expand/src/mbe/macro_check.rs +++ b/compiler/rustc_expand/src/mbe/macro_check.rs @@ -119,9 +119,8 @@ use rustc_span::symbol::{kw, MacroRulesNormalizedIdent}; use rustc_span::{ErrorGuaranteed, Span}; use smallvec::SmallVec; -use super::quoted::VALID_FRAGMENT_NAMES_MSG_2021; -use crate::errors; use crate::mbe::{KleeneToken, TokenTree}; +use crate::{errors, fluent_generated as fluent}; /// Stack represented as linked list. /// @@ -254,7 +253,7 @@ fn check_binders( if let Some(prev_info) = binders.get(&name) { // 1. The meta-variable is already bound in the current LHS: This is an error. let mut span = MultiSpan::from_span(span); - span.push_span_label(prev_info.span, "previous declaration"); + span.push_span_label(prev_info.span, fluent::expand_label_previous_declaration); buffer_lint(psess, span, node_id, BuiltinLintDiag::DuplicateMatcherBinding); } else if get_binder_info(macros, binders, name).is_none() { // 2. The meta-variable is free: This is a binder. @@ -274,7 +273,7 @@ fn check_binders( psess.dcx().emit_err(errors::MissingFragmentSpecifier { span, add_span: span.shrink_to_hi(), - valid: VALID_FRAGMENT_NAMES_MSG_2021, + valid: errors::InvalidFragmentSpecifierValidNames::Edition2021, }); } else { psess.buffer_lint( @@ -638,15 +637,15 @@ fn ops_is_prefix( for (i, binder) in binder_ops.iter().enumerate() { if i >= occurrence_ops.len() { let mut span = MultiSpan::from_span(span); - span.push_span_label(binder.span, "expected repetition"); + span.push_span_label(binder.span, fluent::expand_label_expected_repetition); buffer_lint(psess, span, node_id, BuiltinLintDiag::MetaVariableStillRepeating(name)); return; } let occurrence = &occurrence_ops[i]; if occurrence.op != binder.op { let mut span = MultiSpan::from_span(span); - span.push_span_label(binder.span, "expected repetition"); - span.push_span_label(occurrence.span, "conflicting repetition"); + span.push_span_label(binder.span, fluent::expand_label_expected_repetition); + span.push_span_label(occurrence.span, fluent::expand_label_conflicting_repetition); buffer_lint(psess, span, node_id, BuiltinLintDiag::MetaVariableWrongOperator); return; } diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index e5b9c62742967..cf858d48aa9b9 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -78,14 +78,15 @@ use std::rc::Rc; use rustc_ast::token::{self, DocComment, NonterminalKind, Token}; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::ErrorGuaranteed; -use rustc_lint_defs::pluralize; +use rustc_errors::{DiagArgValue, DiagCtxtHandle, ErrorGuaranteed}; use rustc_parse::parser::{ParseNtResult, Parser}; use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent}; use rustc_span::Span; pub(crate) use NamedMatch::*; pub(crate) use ParseResult::*; +use super::macro_rules::MatchFailureReason; +use crate::errors; use crate::mbe::macro_rules::Tracker; use crate::mbe::{KleeneOp, TokenTree}; @@ -305,6 +306,43 @@ enum EofMatcherPositions { Multiple, } +#[derive(Debug, Clone)] +pub(crate) enum ErrorMessage { + MissingFragmentSpecifier, + MultipleSuccessfulParses, + // FIXME: check if this can ever be reached + DuplicateBindingName(Ident), + MultipleParsingOptions { macro_name: Ident, n: usize, nts: Vec<(NonterminalKind, Ident)> }, +} + +impl ErrorMessage { + pub(crate) fn emit_err(&self, dcx: DiagCtxtHandle<'_>, span: Span) -> ErrorGuaranteed { + match self { + ErrorMessage::MissingFragmentSpecifier => { + dcx.emit_err(errors::MissingFragmentSpecifierThin { span }) + } + ErrorMessage::MultipleSuccessfulParses => { + dcx.emit_err(errors::MultipleSuccessfulParses { span }) + } + ErrorMessage::DuplicateBindingName(bind) => { + dcx.emit_err(errors::DuplicateBindingName { span, bind: bind.clone() }) + } + ErrorMessage::MultipleParsingOptions { macro_name, n, nts } => { + dcx.emit_err(errors::MultipleParsingOptions { + span, + macro_name: macro_name.clone(), + n: *n, + nts: DiagArgValue::StrListSepByOr( + nts.into_iter() + .map(|(kind, bind)| format!("{kind} ('{bind}')").into()) + .collect(), + ), + }) + } + } + } +} + /// Represents the possible results of an attempted parse. pub(crate) enum ParseResult { /// Parsed successfully. @@ -314,7 +352,7 @@ pub(crate) enum ParseResult { /// The usize is the approximate position of the token in the input token stream. Failure(F), /// Fatal error (malformed macro?). Abort compilation. - Error(rustc_span::Span, String), + Error(rustc_span::Span, ErrorMessage), ErrorReported(ErrorGuaranteed), } @@ -562,7 +600,7 @@ impl TtParser { } else { // E.g. `$e` instead of `$e:expr`, reported as a hard error if actually used. // Both this check and the one in `nameize` are necessary, surprisingly. - return Some(Error(span, "missing fragment specifier".to_string())); + return Some(Error(span, ErrorMessage::MissingFragmentSpecifier)); } } MatcherLoc::Eof => { @@ -591,7 +629,7 @@ impl TtParser { self.nameize(matcher, matches) } EofMatcherPositions::Multiple => { - Error(token.span, "ambiguity: multiple successful parses".to_string()) + Error(token.span, ErrorMessage::MultipleSuccessfulParses) } EofMatcherPositions::None => Failure(T::build_failure( Token::new( @@ -599,7 +637,7 @@ impl TtParser { if token.span.is_dummy() { token.span } else { token.span.shrink_to_hi() }, ), approx_position, - "missing tokens in macro arguments", + MatchFailureReason::MissingTokens, )), }) } else { @@ -650,7 +688,7 @@ impl TtParser { return Failure(T::build_failure( parser.token.clone(), parser.approx_token_stream_pos(), - "no rules expected this token in macro call", + MatchFailureReason::UnexpectedToken, )); } @@ -676,15 +714,12 @@ impl TtParser { // We use the span of the metavariable declaration to determine any // edition-specific matching behavior for non-terminals. let nt = match parser.to_mut().parse_nonterminal(kind) { - Err(err) => { - let guarantee = err.with_span_label( + Err(mut err) => { + err.subdiagnostic(errors::NoteParseErrorInMacroArgument { span, - format!( - "while parsing argument for this `{kind}` macro fragment" - ), - ) - .emit(); - return ErrorReported(guarantee); + kind, + }); + return ErrorReported(err.emit()); } Ok(nt) => nt, }; @@ -716,23 +751,19 @@ impl TtParser { .iter() .map(|mp| match &matcher[mp.idx] { MatcherLoc::MetaVarDecl { bind, kind: Some(kind), .. } => { - format!("{kind} ('{bind}')") + (kind.clone(), bind.clone()) } _ => unreachable!(), }) - .collect::>() - .join(" or "); + .collect(); Error( token_span, - format!( - "local ambiguity when calling macro `{}`: multiple parsing options: {}", - self.macro_name, - match self.next_mps.len() { - 0 => format!("built-in NTs {nts}."), - n => format!("built-in NTs {nts} or {n} other option{s}.", s = pluralize!(n)), - } - ), + ErrorMessage::MultipleParsingOptions { + macro_name: self.macro_name, + n: self.next_mps.len(), + nts, + }, ) } @@ -750,13 +781,13 @@ impl TtParser { match ret_val.entry(MacroRulesNormalizedIdent::new(bind)) { Vacant(spot) => spot.insert(res.next().unwrap()), Occupied(..) => { - return Error(span, format!("duplicated bind name: {bind}")); + return Error(span, ErrorMessage::DuplicateBindingName(bind)); } }; } else { // E.g. `$e` instead of `$e:expr`, reported as a hard error if actually used. // Both this check and the one in `parse_tt_inner` are necessary, surprisingly. - return Error(span, "missing fragment specifier".to_string()); + return Error(span, ErrorMessage::MissingFragmentSpecifier); } } } diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 256713ef73000..6f05a3776823a 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -12,7 +12,7 @@ use rustc_ast::{NodeId, DUMMY_NODE_ID}; use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, TransparencyError}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; -use rustc_errors::{Applicability, ErrorGuaranteed}; +use rustc_errors::ErrorGuaranteed; use rustc_feature::Features; use rustc_lint_defs::builtin::{ RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, @@ -33,9 +33,10 @@ use crate::base::{ DummyResult, ExpandResult, ExtCtxt, MacResult, MacroExpanderResult, SyntaxExtension, SyntaxExtensionKind, TTMacroExpander, }; +use crate::errors::{self, InvalidFollowNote, MatchFailureLabel}; use crate::expand::{ensure_complete_parse, parse_ast_fragment, AstFragment, AstFragmentKind}; use crate::mbe; -use crate::mbe::diagnostics::{annotate_doc_comment, parse_failure_msg}; +use crate::mbe::diagnostics::parse_failure_err; use crate::mbe::macro_check; use crate::mbe::macro_parser::NamedMatch::*; use crate::mbe::macro_parser::{Error, ErrorReported, Failure, MatcherLoc, Success, TtParser}; @@ -147,6 +148,21 @@ fn trace_macros_note(cx_expansions: &mut FxIndexMap>, sp: Span cx_expansions.entry(sp).or_default().push(message); } +#[derive(Debug, Copy, Clone)] +pub(super) enum MatchFailureReason { + MissingTokens, + UnexpectedToken, +} + +impl MatchFailureReason { + pub(super) fn into_label(self, sp: Span) -> MatchFailureLabel { + match self { + MatchFailureReason::MissingTokens => MatchFailureLabel::MissingTokens(sp), + MatchFailureReason::UnexpectedToken => MatchFailureLabel::UnexpectedToken(sp), + } + } +} + pub(super) trait Tracker<'matcher> { /// The contents of `ParseResult::Failure`. type Failure; @@ -154,7 +170,7 @@ pub(super) trait Tracker<'matcher> { /// Arm failed to match. If the token is `token::Eof`, it indicates an unexpected /// end of macro invocation. Otherwise, it indicates that no rules expected the given token. /// The usize is the approximate position of the token in the input token stream. - fn build_failure(tok: Token, position: u32, msg: &'static str) -> Self::Failure; + fn build_failure(tok: Token, position: u32, msg: MatchFailureReason) -> Self::Failure; /// This is called before trying to match next MatcherLoc on the current token. fn before_match_loc(&mut self, _parser: &TtParser, _matcher: &'matcher MatcherLoc) {} @@ -183,7 +199,7 @@ pub(super) struct NoopTracker; impl<'matcher> Tracker<'matcher> for NoopTracker { type Failure = (); - fn build_failure(_tok: Token, _position: u32, _msg: &'static str) -> Self::Failure {} + fn build_failure(_tok: Token, _position: u32, _msg: MatchFailureReason) -> Self::Failure {} fn description() -> &'static str { "none" @@ -465,17 +481,20 @@ pub fn compile_declarative_macro( unreachable!("matcher returned something other than Failure after retry"); }; - let s = parse_failure_msg(&token, track.get_expected_token()); let sp = token.span.substitute_dummy(def.span); - let mut err = sess.dcx().struct_span_err(sp, s); - err.span_label(sp, msg); - annotate_doc_comment(&mut err, sess.source_map(), sp); + let err = sess.dcx().create_err(parse_failure_err( + sp, + sess.source_map(), + msg, + token, + track.get_expected_token().cloned(), + )); let guar = err.emit(); return dummy_syn_ext(guar); } Error(sp, msg) => { - let guar = sess.dcx().span_err(sp.substitute_dummy(def.span), msg); - return dummy_syn_ext(guar); + let span = sp.substitute_dummy(def.span); + return dummy_syn_ext(msg.emit_err(sess.dcx(), span)); } ErrorReported(guar) => { return dummy_syn_ext(guar); @@ -554,10 +573,12 @@ pub fn compile_declarative_macro( let (transparency, transparency_error) = attr::find_transparency(&def.attrs, macro_rules); match transparency_error { Some(TransparencyError::UnknownTransparency(value, span)) => { - dcx.span_err(span, format!("unknown macro transparency: `{value}`")); + dcx.emit_err(errors::UnknownMacroTransparency { span, value }); } Some(TransparencyError::MultipleTransparencyAttrs(old_span, new_span)) => { - dcx.span_err(vec![old_span, new_span], "multiple macro transparency attributes"); + dcx.emit_err(errors::MultipleTransparencyAttrs { + spans: vec![old_span, new_span].into(), + }); } None => {} } @@ -622,8 +643,7 @@ fn check_lhs_nt_follows( if let mbe::TokenTree::Delimited(.., delimited) = lhs { check_matcher(sess, def, &delimited.tts) } else { - let msg = "invalid macro matcher; matchers must be contained in balanced delimiters"; - Err(sess.dcx().span_err(lhs.span(), msg)) + Err(sess.dcx().emit_err(errors::UnbalancedDelimsAroundMatcher { span: lhs.span() })) } } @@ -646,7 +666,7 @@ fn is_empty_token_tree(sess: &Session, seq: &mbe::SequenceRepetition) -> bool { iter.next(); } let span = t.span.to(now.span); - sess.dcx().span_note(span, "doc comments are ignored in matcher position"); + sess.dcx().emit_note(errors::DocCommentsIgnoredInMatcherPosition { span }); } mbe::TokenTree::Sequence(_, sub_seq) if (sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore @@ -671,8 +691,9 @@ fn check_lhs_no_empty_seq(sess: &Session, tts: &[mbe::TokenTree]) -> Result<(), TokenTree::Delimited(.., del) => check_lhs_no_empty_seq(sess, &del.tts)?, TokenTree::Sequence(span, seq) => { if is_empty_token_tree(sess, seq) { - let sp = span.entire(); - let guar = sess.dcx().span_err(sp, "repetition matches empty token tree"); + let span = span.entire(); + let guar = + sess.dcx().emit_err(errors::RepetitionMatchesEmptyTokenTree { span }); return Err(guar); } check_lhs_no_empty_seq(sess, &seq.tts)? @@ -686,7 +707,7 @@ fn check_lhs_no_empty_seq(sess: &Session, tts: &[mbe::TokenTree]) -> Result<(), fn check_rhs(sess: &Session, rhs: &mbe::TokenTree) -> Result<(), ErrorGuaranteed> { match *rhs { mbe::TokenTree::Delimited(..) => Ok(()), - _ => Err(sess.dcx().span_err(rhs.span(), "macro rhs must be delimited")), + _ => Err(sess.dcx().emit_err(errors::MacroRhsMustBeDelimited { span: rhs.span() })), } } @@ -1173,61 +1194,41 @@ fn check_matcher_core<'tt>( match is_in_follow(next_token, kind) { IsInFollow::Yes => {} IsInFollow::No(possible) => { - let may_be = if last.tokens.len() == 1 && suffix_first.tokens.len() == 1 - { - "is" - } else { - "may be" - }; + let only_option = + last.tokens.len() == 1 && suffix_first.tokens.len() == 1; - let sp = next_token.span(); - let mut err = sess.dcx().struct_span_err( - sp, - format!( - "`${name}:{frag}` {may_be} followed by `{next}`, which \ - is not allowed for `{frag}` fragments", - name = name, - frag = kind, - next = quoted_tt_to_string(next_token), - may_be = may_be - ), - ); - err.span_label(sp, format!("not allowed after `{kind}` fragments")); - - if kind == NonterminalKind::Pat(PatWithOr) + let suggestion = if kind == NonterminalKind::Pat(PatWithOr) && sess.psess.edition.at_least_rust_2021() && next_token.is_token(&BinOp(token::BinOpToken::Or)) { - let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl( - span, - name, - Some(NonterminalKind::Pat(PatParam { inferred: false })), - )); - err.span_suggestion( + Some(errors::InvalidFollowSuggestion { span, - "try a `pat_param` fragment specifier instead", - suggestion, - Applicability::MaybeIncorrect, - ); - } + suggestion: quoted_tt_to_string(&TokenTree::MetaVarDecl( + span, + name, + Some(NonterminalKind::Pat(PatParam { inferred: false })), + )), + }) + } else { + None + }; - let msg = "allowed there are: "; - match possible { - &[] => {} - &[t] => { - err.note(format!( - "only {t} is allowed after `{kind}` fragments", - )); - } - ts => { - err.note(format!( - "{}{} or {}", - msg, - ts[..ts.len() - 1].to_vec().join(", "), - ts[ts.len() - 1], - )); - } - } + let note_allowed = (possible.len() != 0).then(|| InvalidFollowNote { + num_possible: possible.len(), + possible: rustc_errors::DiagArgValue::StrListSepByOr( + possible.into_iter().copied().map(Cow::Borrowed).collect(), + ), + }); + + let err = sess.dcx().create_err(errors::InvalidFollow { + span: next_token.span(), + name, + kind, + next: quoted_tt_to_string(next_token), + only_option, + suggestion, + note_allowed, + }); errored = Err(err.emit()); } } diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs index a7d9a0c97a22e..350aff02f117b 100644 --- a/compiler/rustc_expand/src/mbe/metavar_expr.rs +++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs @@ -1,15 +1,13 @@ use rustc_ast::token::{self, Delimiter, IdentIsRaw, Lit, Token, TokenKind}; use rustc_ast::tokenstream::{RefTokenTreeCursor, TokenStream, TokenTree}; use rustc_ast::{LitIntType, LitKind}; -use rustc_ast_pretty::pprust; -use rustc_errors::{Applicability, PResult}; +use rustc_errors::PResult; use rustc_macros::{Decodable, Encodable}; use rustc_session::parse::ParseSess; use rustc_span::symbol::Ident; use rustc_span::{Span, Symbol}; -pub(crate) const RAW_IDENT_ERR: &str = "`${concat(..)}` currently does not support raw identifiers"; -pub(crate) const UNSUPPORTED_CONCAT_ELEM_ERR: &str = "expected identifier or string literal"; +use crate::errors; /// A meta-variable expression, for expansions based on properties of meta-variables. #[derive(Debug, PartialEq, Encodable, Decodable)] @@ -42,8 +40,9 @@ impl MetaVarExpr { let mut tts = input.trees(); let ident = parse_ident(&mut tts, psess, outer_span)?; let Some(TokenTree::Delimited(.., Delimiter::Parenthesis, args)) = tts.next() else { - let msg = "meta-variable expression parameter must be wrapped in parentheses"; - return Err(psess.dcx().struct_span_err(ident.span, msg)); + return Err(psess + .dcx() + .create_err(errors::MetaVarExprParamNeedsParens { span: ident.span })); }; check_trailing_token(&mut tts, psess)?; let mut iter = args.trees(); @@ -66,9 +65,9 @@ impl MetaVarExpr { match parse_ident_from_token(psess, token) { Err(err) => { err.cancel(); - return Err(psess - .dcx() - .struct_span_err(token.span, UNSUPPORTED_CONCAT_ELEM_ERR)); + return Err(psess.dcx().create_err( + errors::UnsupportedConcatElem { span: token.span }, + )); } Ok(elem) => MetaVarExprConcatElem::Ident(elem), } @@ -78,13 +77,15 @@ impl MetaVarExpr { break; } if !try_eat_comma(&mut iter) { - return Err(psess.dcx().struct_span_err(outer_span, "expected comma")); + return Err(psess + .dcx() + .create_err(errors::ExpectedComma { span: outer_span })); } } if result.len() < 2 { return Err(psess .dcx() - .struct_span_err(ident.span, "`concat` must have at least two elements")); + .create_err(errors::ConcatTooFewArgs { span: ident.span })); } MetaVarExpr::Concat(result.into()) } @@ -96,12 +97,9 @@ impl MetaVarExpr { "index" => MetaVarExpr::Index(parse_depth(&mut iter, psess, ident.span)?), "len" => MetaVarExpr::Len(parse_depth(&mut iter, psess, ident.span)?), _ => { - let err_msg = "unrecognized meta-variable expression"; - let mut err = psess.dcx().struct_span_err(ident.span, err_msg); - err.help( - "supported expressions are count, ignore, index and len", - ); - return Err(err); + return Err(psess + .dcx() + .create_err(errors::UnrecognizedMetaVarExpr { span: ident.span })); } }; check_trailing_token(&mut iter, psess)?; @@ -144,11 +142,9 @@ fn check_trailing_token<'psess>( psess: &'psess ParseSess, ) -> PResult<'psess, ()> { if let Some(tt) = iter.next() { - let mut diag = psess + Err(psess .dcx() - .struct_span_err(tt.span(), format!("unexpected token: {}", pprust::tt_to_string(tt))); - diag.span_note(tt.span(), "meta-variable expression must not have trailing tokens"); - Err(diag) + .create_err(errors::MetaVarExprUnexpectedToken { span: tt.span(), tt: tt.clone() })) } else { Ok(()) } @@ -164,10 +160,7 @@ fn parse_count<'psess>( let ident = parse_ident(iter, psess, span)?; let depth = if try_eat_comma(iter) { if iter.look_ahead(0).is_none() { - return Err(psess.dcx().struct_span_err( - span, - "`count` followed by a comma must have an associated index indicating its depth", - )); + return Err(psess.dcx().create_err(errors::CountWithCommaNoIndex { span })); } parse_depth(iter, psess, span)? } else { @@ -184,9 +177,7 @@ fn parse_depth<'psess>( ) -> PResult<'psess, usize> { let Some(tt) = iter.next() else { return Ok(0) }; let TokenTree::Token(Token { kind: TokenKind::Literal(lit), .. }, _) = tt else { - return Err(psess - .dcx() - .struct_span_err(span, "meta-variable expression depth must be a literal")); + return Err(psess.dcx().create_err(errors::MetaVarExprDepthNotLiteral { span })); }; if let Ok(lit_kind) = LitKind::from_token_lit(*lit) && let LitKind::Int(n_u128, LitIntType::Unsuffixed) = lit_kind @@ -194,8 +185,7 @@ fn parse_depth<'psess>( { Ok(n_usize) } else { - let msg = "only unsuffixed integer literals are supported in meta-variable expressions"; - Err(psess.dcx().struct_span_err(span, msg)) + Err(psess.dcx().create_err(errors::MetaVarExprDepthSuffixed { span })) } } @@ -215,21 +205,14 @@ fn parse_ident_from_token<'psess>( ) -> PResult<'psess, Ident> { if let Some((elem, is_raw)) = token.ident() { if let IdentIsRaw::Yes = is_raw { - return Err(psess.dcx().struct_span_err(elem.span, RAW_IDENT_ERR)); + return Err(psess.dcx().create_err(errors::ConcatRawIdent { span: elem.span })); } return Ok(elem); } - let token_str = pprust::token_to_string(token); - let mut err = psess - .dcx() - .struct_span_err(token.span, format!("expected identifier, found `{token_str}`")); - err.span_suggestion( - token.span, - format!("try removing `{token_str}`"), - "", - Applicability::MaybeIncorrect, - ); - Err(err) + Err(psess.dcx().create_err(errors::MetaVarExprExpectedIdentifier { + span: token.span, + found: token.clone(), + })) } fn parse_token<'psess, 't>( @@ -238,10 +221,10 @@ fn parse_token<'psess, 't>( fallback_span: Span, ) -> PResult<'psess, &'t Token> { let Some(tt) = iter.next() else { - return Err(psess.dcx().struct_span_err(fallback_span, UNSUPPORTED_CONCAT_ELEM_ERR)); + return Err(psess.dcx().create_err(errors::UnsupportedConcatElem { span: fallback_span })); }; let TokenTree::Token(token, _) = tt else { - return Err(psess.dcx().struct_span_err(tt.span(), UNSUPPORTED_CONCAT_ELEM_ERR)); + return Err(psess.dcx().create_err(errors::UnsupportedConcatElem { span: tt.span() })); }; Ok(token) } @@ -276,8 +259,5 @@ fn eat_dollar<'psess>( let _ = iter.next(); return Ok(()); } - Err(psess.dcx().struct_span_err( - span, - "meta-variables within meta-variable expressions must be referenced using a dollar sign", - )) + Err(psess.dcx().create_err(errors::NestedMetaVarExprWithoutDollar { span })) } diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index b2f7c8f5183a2..a75a9d6645870 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -9,17 +9,9 @@ use rustc_span::edition::Edition; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; -use crate::errors; use crate::mbe::macro_parser::count_metavar_decls; use crate::mbe::{Delimited, KleeneOp, KleeneToken, MetaVarExpr, SequenceRepetition, TokenTree}; - -const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \ - `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \ - `literal`, `path`, `meta`, `tt`, `item` and `vis`"; -pub const VALID_FRAGMENT_NAMES_MSG_2021: &str = "valid fragment specifiers are \ - `ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, \ - `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, \ - `item` and `vis`"; +use crate::{errors, fluent_generated as fluent}; /// Takes a `tokenstream::TokenStream` and returns a `Vec`. Specifically, this /// takes a generic `TokenStream`, such as is used in the rest of the compiler, and returns a @@ -93,26 +85,31 @@ pub(super) fn parse( }; let kind = NonterminalKind::from_symbol(fragment.name, edition) .unwrap_or_else(|| { - let help = match fragment.name { - sym::expr_2021 => { - format!( - "fragment specifier `expr_2021` \ - requires Rust 2021 or later\n\ - {VALID_FRAGMENT_NAMES_MSG}" - ) - } + let (help_expr_2021, help_valid_names) = match fragment.name { + sym::expr_2021 => ( + true, + errors::InvalidFragmentSpecifierValidNames::Other, + ), _ if edition().at_least_rust_2021() && features.expr_fragment_specifier_2024 => - { - VALID_FRAGMENT_NAMES_MSG_2021.into() - } - _ => VALID_FRAGMENT_NAMES_MSG.into(), + ( + false, + errors::InvalidFragmentSpecifierValidNames::Edition2021, + ), + _ => ( + false, + errors::InvalidFragmentSpecifierValidNames::Other, + ) + }; - sess.dcx().emit_err(errors::InvalidFragmentSpecifier { - span, - fragment, - help, - }); + sess.dcx().emit_err( + errors::InvalidFragmentSpecifier { + span, + fragment, + help_expr_2021, + help_valid_names, + }, + ); NonterminalKind::Ident }); if kind == NonterminalKind::Expr(Expr2021 { inferred: false }) @@ -122,7 +119,7 @@ pub(super) fn parse( sess, sym::expr_fragment_specifier_2024, span, - "fragment specifier `expr_2021` is unstable", + fluent::expand_expr_2021_unstable, ) .emit(); } @@ -153,15 +150,20 @@ pub(super) fn parse( /// Asks for the `macro_metavar_expr` feature if it is not already declared fn maybe_emit_macro_metavar_expr_feature(features: &Features, sess: &Session, span: Span) { if !features.macro_metavar_expr { - let msg = "meta-variable expressions are unstable"; - feature_err(sess, sym::macro_metavar_expr, span, msg).emit(); + feature_err(sess, sym::macro_metavar_expr, span, fluent::expand_meta_var_expr_unstable) + .emit(); } } fn maybe_emit_macro_metavar_expr_concat_feature(features: &Features, sess: &Session, span: Span) { if !features.macro_metavar_expr_concat { - let msg = "the `concat` meta-variable expression is unstable"; - feature_err(sess, sym::macro_metavar_expr_concat, span, msg).emit(); + feature_err( + sess, + sym::macro_metavar_expr_concat, + span, + fluent::expand_meta_var_expr_concat_unstable, + ) + .emit(); } } @@ -300,9 +302,10 @@ fn parse_tree<'a>( // `tree` is followed by some other token. This is an error. Some(tokenstream::TokenTree::Token(token, _)) => { - let msg = - format!("expected identifier, found `{}`", pprust::token_to_string(token),); - sess.dcx().span_err(token.span, msg); + sess.dcx().emit_err(errors::ExpectedIdentifier { + span: token.span, + found: token.clone(), + }); TokenTree::MetaVar(token.span, Ident::empty()) } @@ -383,10 +386,7 @@ fn parse_sep_and_kleene_op<'a>( // #2 is the `?` Kleene op, which does not take a separator (error) Ok(Ok((KleeneOp::ZeroOrOne, span))) => { // Error! - sess.dcx().span_err( - token.span, - "the `?` macro repetition operator does not take a separator", - ); + sess.dcx().emit_err(errors::QuestionMarkWithSeparator { span: token.span }); // Return a dummy return (None, KleeneToken::new(KleeneOp::ZeroOrMore, span)); @@ -404,7 +404,7 @@ fn parse_sep_and_kleene_op<'a>( }; // If we ever get to this point, we have experienced an "unexpected token" error - sess.dcx().span_err(span, "expected one of: `*`, `+`, or `?`"); + sess.dcx().emit_err(errors::ExpectedRepetitionOperator { span }); // Return a dummy (None, KleeneToken::new(KleeneOp::ZeroOrMore, span)) @@ -414,10 +414,5 @@ fn parse_sep_and_kleene_op<'a>( // // For example, `macro_rules! foo { ( ${len()} ) => {} }` fn span_dollar_dollar_or_metavar_in_the_lhs_err(sess: &Session, token: &Token) { - sess.dcx() - .span_err(token.span, format!("unexpected token: {}", pprust::token_to_string(token))); - sess.dcx().span_note( - token.span, - "`$$` and meta-variable expressions are not allowed inside macro parameter definitions", - ); + sess.dcx().emit_err(errors::DollarOrMetavarInLhs { span: token.span, token: token.clone() }); } diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index b06910595bb25..24e311523ca8d 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -5,7 +5,7 @@ use rustc_ast::token::{self, Delimiter, IdentIsRaw, Lit, LitKind, Nonterminal, T use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; use rustc_ast::ExprKind; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{pluralize, Diag, DiagCtxtHandle, PResult}; +use rustc_errors::{Diag, DiagCtxtHandle, PResult}; use rustc_parse::lexer::nfc_normalize; use rustc_parse::parser::ParseNtResult; use rustc_session::parse::{ParseSess, SymbolGallery}; @@ -15,12 +15,12 @@ use rustc_span::{with_metavar_spans, Span, Symbol, SyntaxContext}; use smallvec::{smallvec, SmallVec}; use crate::errors::{ - CountRepetitionMisplaced, MetaVarExprUnrecognizedVar, MetaVarsDifSeqMatchers, MustRepeatOnce, - NoSyntaxVarsExprRepeat, VarStillRepeating, + self, CountRepetitionMisplaced, MetaVarExprUnrecognizedVar, MetaVarsDifSeqMatchers, + MustRepeatOnce, NoSyntaxVarsExprRepeat, VarStillRepeating, }; use crate::mbe::macro_parser::NamedMatch; use crate::mbe::macro_parser::NamedMatch::*; -use crate::mbe::metavar_expr::{MetaVarExprConcatElem, RAW_IDENT_ERR}; +use crate::mbe::metavar_expr::MetaVarExprConcatElem; use crate::mbe::{self, KleeneOp, MetaVarExpr}; // A Marker adds the given mark to the syntax context. @@ -211,14 +211,18 @@ pub(super) fn transcribe<'a>( return Err(dcx.create_err(NoSyntaxVarsExprRepeat { span: seq.span() })); } - LockstepIterSize::Contradiction(msg) => { + LockstepIterSize::Contradiction { var1_id, var1_len, var2_id, var2_len } => { // FIXME: this really ought to be caught at macro definition time... It // happens when two meta-variables are used in the same repetition in a // sequence, but they come from different sequence matchers and repeat // different amounts. - return Err( - dcx.create_err(MetaVarsDifSeqMatchers { span: seq.span(), msg }) - ); + return Err(dcx.create_err(MetaVarsDifSeqMatchers { + span: seq.span(), + var1_id, + var1_len, + var2_id, + var2_len, + })); } LockstepIterSize::Constraint(len, _) => { @@ -485,7 +489,7 @@ enum LockstepIterSize { Constraint(usize, MacroRulesNormalizedIdent), /// Two `Constraint`s on the same sequence had different lengths. This is an error. - Contradiction(String), + Contradiction { var1_id: String, var1_len: usize, var2_id: String, var2_len: usize }, } impl LockstepIterSize { @@ -496,23 +500,17 @@ impl LockstepIterSize { fn with(self, other: LockstepIterSize) -> LockstepIterSize { match self { LockstepIterSize::Unconstrained => other, - LockstepIterSize::Contradiction(_) => self, + LockstepIterSize::Contradiction { .. } => self, LockstepIterSize::Constraint(l_len, l_id) => match other { LockstepIterSize::Unconstrained => self, - LockstepIterSize::Contradiction(_) => other, + LockstepIterSize::Contradiction { .. } => other, LockstepIterSize::Constraint(r_len, _) if l_len == r_len => self, - LockstepIterSize::Constraint(r_len, r_id) => { - let msg = format!( - "meta-variable `{}` repeats {} time{}, but `{}` repeats {} time{}", - l_id, - l_len, - pluralize!(l_len), - r_id, - r_len, - pluralize!(r_len), - ); - LockstepIterSize::Contradiction(msg) - } + LockstepIterSize::Constraint(r_len, r_id) => LockstepIterSize::Contradiction { + var1_id: l_id.to_string(), + var1_len: l_len, + var2_id: r_id.to_string(), + var2_len: r_len, + }, }, } } @@ -656,18 +654,7 @@ where /// Used by meta-variable expressions when an user input is out of the actual declared bounds. For /// example, index(999999) in an repetition of only three elements. fn out_of_bounds_err<'a>(dcx: DiagCtxtHandle<'a>, max: usize, span: Span, ty: &str) -> Diag<'a> { - let msg = if max == 0 { - format!( - "meta-variable expression `{ty}` with depth parameter \ - must be called inside of a macro repetition" - ) - } else { - format!( - "depth parameter of meta-variable expression `{ty}` \ - must be less than {max}" - ) - }; - dcx.struct_span_err(span, msg) + dcx.create_err(errors::MetaVarExprOutOfBounds { span, ty: ty.to_string(), max }) } fn transcribe_metavar_expr<'a>( @@ -715,10 +702,9 @@ fn transcribe_metavar_expr<'a>( let symbol = nfc_normalize(&concatenated); let concatenated_span = visited_span(); if !rustc_lexer::is_ident(symbol.as_str()) { - return Err(dcx.struct_span_err( - concatenated_span, - "`${concat(..)}` is not generating a valid identifier", - )); + return Err( + dcx.create_err(errors::ConcatGeneratedInvalidIdent { span: concatenated_span }) + ); } symbol_gallery.insert(symbol, concatenated_span); // The current implementation marks the span as coming from the macro regardless of @@ -773,7 +759,7 @@ fn extract_symbol_from_pnr<'a>( match pnr { ParseNtResult::Ident(nt_ident, is_raw) => { if let IdentIsRaw::Yes = is_raw { - return Err(dcx.struct_span_err(span_err, RAW_IDENT_ERR)); + return Err(dcx.create_err(errors::ConcatRawIdent { span: span_err })); } return Ok(nt_ident.name); } @@ -782,7 +768,7 @@ fn extract_symbol_from_pnr<'a>( _, )) => { if let IdentIsRaw::Yes = is_raw { - return Err(dcx.struct_span_err(span_err, RAW_IDENT_ERR)); + return Err(dcx.create_err(errors::ConcatRawIdent { span: span_err })); } return Ok(*symbol); } @@ -802,11 +788,6 @@ fn extract_symbol_from_pnr<'a>( { return Ok(*symbol); } - _ => Err(dcx - .struct_err( - "metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt`", - ) - .with_note("currently only string literals are supported") - .with_span(span_err)), + _ => Err(dcx.create_err(errors::InvalidConcatArgType { span: span_err })), } } diff --git a/tests/ui/lint/unused/unused-macro-with-follow-violation.stderr b/tests/ui/lint/unused/unused-macro-with-follow-violation.stderr index a8a41e081294a..e25fcfb9aa0a5 100644 --- a/tests/ui/lint/unused/unused-macro-with-follow-violation.stderr +++ b/tests/ui/lint/unused/unused-macro-with-follow-violation.stderr @@ -4,7 +4,7 @@ error: `$e:expr` is followed by `+`, which is not allowed for `expr` fragments LL | ($e:expr +) => () | ^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: aborting due to 1 previous error diff --git a/tests/ui/macros/macro-follow.stderr b/tests/ui/macros/macro-follow.stderr index 61ae79d235ee5..ccd3c4c45185d 100644 --- a/tests/ui/macros/macro-follow.stderr +++ b/tests/ui/macros/macro-follow.stderr @@ -4,7 +4,7 @@ error: `$p:pat` is followed by `(`, which is not allowed for `pat` fragments LL | ($p:pat ()) => {}; | ^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$p:pat` is followed by `[`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:9:13 @@ -12,7 +12,7 @@ error: `$p:pat` is followed by `[`, which is not allowed for `pat` fragments LL | ($p:pat []) => {}; | ^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$p:pat` is followed by `{`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:10:13 @@ -20,7 +20,7 @@ error: `$p:pat` is followed by `{`, which is not allowed for `pat` fragments LL | ($p:pat {}) => {}; | ^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$p:pat` is followed by `:`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:11:13 @@ -28,7 +28,7 @@ error: `$p:pat` is followed by `:`, which is not allowed for `pat` fragments LL | ($p:pat :) => {}; | ^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$p:pat` is followed by `>`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:12:13 @@ -36,7 +36,7 @@ error: `$p:pat` is followed by `>`, which is not allowed for `pat` fragments LL | ($p:pat >) => {}; | ^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$p:pat` is followed by `+`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:13:13 @@ -44,7 +44,7 @@ error: `$p:pat` is followed by `+`, which is not allowed for `pat` fragments LL | ($p:pat +) => {}; | ^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$p:pat` is followed by `ident`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:14:13 @@ -52,7 +52,7 @@ error: `$p:pat` is followed by `ident`, which is not allowed for `pat` fragments LL | ($p:pat ident) => {}; | ^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$p:pat` is followed by `$q:pat`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:15:13 @@ -60,7 +60,7 @@ error: `$p:pat` is followed by `$q:pat`, which is not allowed for `pat` fragment LL | ($p:pat $q:pat) => {}; | ^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$p:pat` is followed by `$e:expr`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:16:13 @@ -68,7 +68,7 @@ error: `$p:pat` is followed by `$e:expr`, which is not allowed for `pat` fragmen LL | ($p:pat $e:expr) => {}; | ^^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$p:pat` is followed by `$t:ty`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:17:13 @@ -76,7 +76,7 @@ error: `$p:pat` is followed by `$t:ty`, which is not allowed for `pat` fragments LL | ($p:pat $t:ty) => {}; | ^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$p:pat` is followed by `$s:stmt`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:18:13 @@ -84,7 +84,7 @@ error: `$p:pat` is followed by `$s:stmt`, which is not allowed for `pat` fragmen LL | ($p:pat $s:stmt) => {}; | ^^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$p:pat` is followed by `$q:path`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:19:13 @@ -92,7 +92,7 @@ error: `$p:pat` is followed by `$q:path`, which is not allowed for `pat` fragmen LL | ($p:pat $q:path) => {}; | ^^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$p:pat` is followed by `$b:block`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:20:13 @@ -100,7 +100,7 @@ error: `$p:pat` is followed by `$b:block`, which is not allowed for `pat` fragme LL | ($p:pat $b:block) => {}; | ^^^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$p:pat` is followed by `$i:ident`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:21:13 @@ -108,7 +108,7 @@ error: `$p:pat` is followed by `$i:ident`, which is not allowed for `pat` fragme LL | ($p:pat $i:ident) => {}; | ^^^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$p:pat` is followed by `$t:tt`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:22:13 @@ -116,7 +116,7 @@ error: `$p:pat` is followed by `$t:tt`, which is not allowed for `pat` fragments LL | ($p:pat $t:tt) => {}; | ^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$p:pat` is followed by `$i:item`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:23:13 @@ -124,7 +124,7 @@ error: `$p:pat` is followed by `$i:item`, which is not allowed for `pat` fragmen LL | ($p:pat $i:item) => {}; | ^^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$p:pat` is followed by `$m:meta`, which is not allowed for `pat` fragments --> $DIR/macro-follow.rs:24:13 @@ -132,7 +132,7 @@ error: `$p:pat` is followed by `$m:meta`, which is not allowed for `pat` fragmen LL | ($p:pat $m:meta) => {}; | ^^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$e:expr` is followed by `(`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:28:14 @@ -140,7 +140,7 @@ error: `$e:expr` is followed by `(`, which is not allowed for `expr` fragments LL | ($e:expr ()) => {}; | ^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `[`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:29:14 @@ -148,7 +148,7 @@ error: `$e:expr` is followed by `[`, which is not allowed for `expr` fragments LL | ($e:expr []) => {}; | ^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `{`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:30:14 @@ -156,7 +156,7 @@ error: `$e:expr` is followed by `{`, which is not allowed for `expr` fragments LL | ($e:expr {}) => {}; | ^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `=`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:31:14 @@ -164,7 +164,7 @@ error: `$e:expr` is followed by `=`, which is not allowed for `expr` fragments LL | ($e:expr =) => {}; | ^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `|`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:32:14 @@ -172,7 +172,7 @@ error: `$e:expr` is followed by `|`, which is not allowed for `expr` fragments LL | ($e:expr |) => {}; | ^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `:`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:33:14 @@ -180,7 +180,7 @@ error: `$e:expr` is followed by `:`, which is not allowed for `expr` fragments LL | ($e:expr :) => {}; | ^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `>`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:34:14 @@ -188,7 +188,7 @@ error: `$e:expr` is followed by `>`, which is not allowed for `expr` fragments LL | ($e:expr >) => {}; | ^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `+`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:35:14 @@ -196,7 +196,7 @@ error: `$e:expr` is followed by `+`, which is not allowed for `expr` fragments LL | ($e:expr +) => {}; | ^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `ident`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:36:14 @@ -204,7 +204,7 @@ error: `$e:expr` is followed by `ident`, which is not allowed for `expr` fragmen LL | ($e:expr ident) => {}; | ^^^^^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `if`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:37:14 @@ -212,7 +212,7 @@ error: `$e:expr` is followed by `if`, which is not allowed for `expr` fragments LL | ($e:expr if) => {}; | ^^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `in`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:38:14 @@ -220,7 +220,7 @@ error: `$e:expr` is followed by `in`, which is not allowed for `expr` fragments LL | ($e:expr in) => {}; | ^^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `$p:pat`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:39:14 @@ -228,7 +228,7 @@ error: `$e:expr` is followed by `$p:pat`, which is not allowed for `expr` fragme LL | ($e:expr $p:pat) => {}; | ^^^^^^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `$f:expr`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:40:14 @@ -236,7 +236,7 @@ error: `$e:expr` is followed by `$f:expr`, which is not allowed for `expr` fragm LL | ($e:expr $f:expr) => {}; | ^^^^^^^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `$t:ty`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:41:14 @@ -244,7 +244,7 @@ error: `$e:expr` is followed by `$t:ty`, which is not allowed for `expr` fragmen LL | ($e:expr $t:ty) => {}; | ^^^^^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `$s:stmt`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:42:14 @@ -252,7 +252,7 @@ error: `$e:expr` is followed by `$s:stmt`, which is not allowed for `expr` fragm LL | ($e:expr $s:stmt) => {}; | ^^^^^^^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `$p:path`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:43:14 @@ -260,7 +260,7 @@ error: `$e:expr` is followed by `$p:path`, which is not allowed for `expr` fragm LL | ($e:expr $p:path) => {}; | ^^^^^^^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `$b:block`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:44:14 @@ -268,7 +268,7 @@ error: `$e:expr` is followed by `$b:block`, which is not allowed for `expr` frag LL | ($e:expr $b:block) => {}; | ^^^^^^^^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `$i:ident`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:45:14 @@ -276,7 +276,7 @@ error: `$e:expr` is followed by `$i:ident`, which is not allowed for `expr` frag LL | ($e:expr $i:ident) => {}; | ^^^^^^^^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `$t:tt`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:46:14 @@ -284,7 +284,7 @@ error: `$e:expr` is followed by `$t:tt`, which is not allowed for `expr` fragmen LL | ($e:expr $t:tt) => {}; | ^^^^^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `$i:item`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:47:14 @@ -292,7 +292,7 @@ error: `$e:expr` is followed by `$i:item`, which is not allowed for `expr` fragm LL | ($e:expr $i:item) => {}; | ^^^^^^^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$e:expr` is followed by `$m:meta`, which is not allowed for `expr` fragments --> $DIR/macro-follow.rs:48:14 @@ -300,7 +300,7 @@ error: `$e:expr` is followed by `$m:meta`, which is not allowed for `expr` fragm LL | ($e:expr $m:meta) => {}; | ^^^^^^^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$t:ty` is followed by `(`, which is not allowed for `ty` fragments --> $DIR/macro-follow.rs:53:12 @@ -308,7 +308,7 @@ error: `$t:ty` is followed by `(`, which is not allowed for `ty` fragments LL | ($t:ty ()) => {}; | ^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$t:ty` is followed by `+`, which is not allowed for `ty` fragments --> $DIR/macro-follow.rs:55:12 @@ -316,7 +316,7 @@ error: `$t:ty` is followed by `+`, which is not allowed for `ty` fragments LL | ($t:ty +) => {}; | ^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$t:ty` is followed by `ident`, which is not allowed for `ty` fragments --> $DIR/macro-follow.rs:56:12 @@ -324,7 +324,7 @@ error: `$t:ty` is followed by `ident`, which is not allowed for `ty` fragments LL | ($t:ty ident) => {}; | ^^^^^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$t:ty` is followed by `if`, which is not allowed for `ty` fragments --> $DIR/macro-follow.rs:57:12 @@ -332,7 +332,7 @@ error: `$t:ty` is followed by `if`, which is not allowed for `ty` fragments LL | ($t:ty if) => {}; | ^^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$t:ty` is followed by `$p:pat`, which is not allowed for `ty` fragments --> $DIR/macro-follow.rs:58:12 @@ -340,7 +340,7 @@ error: `$t:ty` is followed by `$p:pat`, which is not allowed for `ty` fragments LL | ($t:ty $p:pat) => {}; | ^^^^^^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$t:ty` is followed by `$e:expr`, which is not allowed for `ty` fragments --> $DIR/macro-follow.rs:59:12 @@ -348,7 +348,7 @@ error: `$t:ty` is followed by `$e:expr`, which is not allowed for `ty` fragments LL | ($t:ty $e:expr) => {}; | ^^^^^^^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$t:ty` is followed by `$r:ty`, which is not allowed for `ty` fragments --> $DIR/macro-follow.rs:60:12 @@ -356,7 +356,7 @@ error: `$t:ty` is followed by `$r:ty`, which is not allowed for `ty` fragments LL | ($t:ty $r:ty) => {}; | ^^^^^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$t:ty` is followed by `$s:stmt`, which is not allowed for `ty` fragments --> $DIR/macro-follow.rs:61:12 @@ -364,7 +364,7 @@ error: `$t:ty` is followed by `$s:stmt`, which is not allowed for `ty` fragments LL | ($t:ty $s:stmt) => {}; | ^^^^^^^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$t:ty` is followed by `$p:path`, which is not allowed for `ty` fragments --> $DIR/macro-follow.rs:62:12 @@ -372,7 +372,7 @@ error: `$t:ty` is followed by `$p:path`, which is not allowed for `ty` fragments LL | ($t:ty $p:path) => {}; | ^^^^^^^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$t:ty` is followed by `$i:ident`, which is not allowed for `ty` fragments --> $DIR/macro-follow.rs:64:12 @@ -380,7 +380,7 @@ error: `$t:ty` is followed by `$i:ident`, which is not allowed for `ty` fragment LL | ($t:ty $i:ident) => {}; | ^^^^^^^^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$t:ty` is followed by `$r:tt`, which is not allowed for `ty` fragments --> $DIR/macro-follow.rs:65:12 @@ -388,7 +388,7 @@ error: `$t:ty` is followed by `$r:tt`, which is not allowed for `ty` fragments LL | ($t:ty $r:tt) => {}; | ^^^^^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$t:ty` is followed by `$i:item`, which is not allowed for `ty` fragments --> $DIR/macro-follow.rs:66:12 @@ -396,7 +396,7 @@ error: `$t:ty` is followed by `$i:item`, which is not allowed for `ty` fragments LL | ($t:ty $i:item) => {}; | ^^^^^^^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$t:ty` is followed by `$m:meta`, which is not allowed for `ty` fragments --> $DIR/macro-follow.rs:67:12 @@ -404,7 +404,7 @@ error: `$t:ty` is followed by `$m:meta`, which is not allowed for `ty` fragments LL | ($t:ty $m:meta) => {}; | ^^^^^^^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$s:stmt` is followed by `(`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:71:14 @@ -412,7 +412,7 @@ error: `$s:stmt` is followed by `(`, which is not allowed for `stmt` fragments LL | ($s:stmt ()) => {}; | ^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `[`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:72:14 @@ -420,7 +420,7 @@ error: `$s:stmt` is followed by `[`, which is not allowed for `stmt` fragments LL | ($s:stmt []) => {}; | ^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `{`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:73:14 @@ -428,7 +428,7 @@ error: `$s:stmt` is followed by `{`, which is not allowed for `stmt` fragments LL | ($s:stmt {}) => {}; | ^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `=`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:74:14 @@ -436,7 +436,7 @@ error: `$s:stmt` is followed by `=`, which is not allowed for `stmt` fragments LL | ($s:stmt =) => {}; | ^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `|`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:75:14 @@ -444,7 +444,7 @@ error: `$s:stmt` is followed by `|`, which is not allowed for `stmt` fragments LL | ($s:stmt |) => {}; | ^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `:`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:76:14 @@ -452,7 +452,7 @@ error: `$s:stmt` is followed by `:`, which is not allowed for `stmt` fragments LL | ($s:stmt :) => {}; | ^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `>`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:77:14 @@ -460,7 +460,7 @@ error: `$s:stmt` is followed by `>`, which is not allowed for `stmt` fragments LL | ($s:stmt >) => {}; | ^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `+`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:78:14 @@ -468,7 +468,7 @@ error: `$s:stmt` is followed by `+`, which is not allowed for `stmt` fragments LL | ($s:stmt +) => {}; | ^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `ident`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:79:14 @@ -476,7 +476,7 @@ error: `$s:stmt` is followed by `ident`, which is not allowed for `stmt` fragmen LL | ($s:stmt ident) => {}; | ^^^^^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `if`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:80:14 @@ -484,7 +484,7 @@ error: `$s:stmt` is followed by `if`, which is not allowed for `stmt` fragments LL | ($s:stmt if) => {}; | ^^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `in`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:81:14 @@ -492,7 +492,7 @@ error: `$s:stmt` is followed by `in`, which is not allowed for `stmt` fragments LL | ($s:stmt in) => {}; | ^^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `$p:pat`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:82:14 @@ -500,7 +500,7 @@ error: `$s:stmt` is followed by `$p:pat`, which is not allowed for `stmt` fragme LL | ($s:stmt $p:pat) => {}; | ^^^^^^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `$e:expr`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:83:14 @@ -508,7 +508,7 @@ error: `$s:stmt` is followed by `$e:expr`, which is not allowed for `stmt` fragm LL | ($s:stmt $e:expr) => {}; | ^^^^^^^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `$t:ty`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:84:14 @@ -516,7 +516,7 @@ error: `$s:stmt` is followed by `$t:ty`, which is not allowed for `stmt` fragmen LL | ($s:stmt $t:ty) => {}; | ^^^^^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `$t:stmt`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:85:14 @@ -524,7 +524,7 @@ error: `$s:stmt` is followed by `$t:stmt`, which is not allowed for `stmt` fragm LL | ($s:stmt $t:stmt) => {}; | ^^^^^^^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `$p:path`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:86:14 @@ -532,7 +532,7 @@ error: `$s:stmt` is followed by `$p:path`, which is not allowed for `stmt` fragm LL | ($s:stmt $p:path) => {}; | ^^^^^^^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `$b:block`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:87:14 @@ -540,7 +540,7 @@ error: `$s:stmt` is followed by `$b:block`, which is not allowed for `stmt` frag LL | ($s:stmt $b:block) => {}; | ^^^^^^^^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `$i:ident`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:88:14 @@ -548,7 +548,7 @@ error: `$s:stmt` is followed by `$i:ident`, which is not allowed for `stmt` frag LL | ($s:stmt $i:ident) => {}; | ^^^^^^^^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `$t:tt`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:89:14 @@ -556,7 +556,7 @@ error: `$s:stmt` is followed by `$t:tt`, which is not allowed for `stmt` fragmen LL | ($s:stmt $t:tt) => {}; | ^^^^^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `$i:item`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:90:14 @@ -564,7 +564,7 @@ error: `$s:stmt` is followed by `$i:item`, which is not allowed for `stmt` fragm LL | ($s:stmt $i:item) => {}; | ^^^^^^^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$s:stmt` is followed by `$m:meta`, which is not allowed for `stmt` fragments --> $DIR/macro-follow.rs:91:14 @@ -572,7 +572,7 @@ error: `$s:stmt` is followed by `$m:meta`, which is not allowed for `stmt` fragm LL | ($s:stmt $m:meta) => {}; | ^^^^^^^ not allowed after `stmt` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$p:path` is followed by `(`, which is not allowed for `path` fragments --> $DIR/macro-follow.rs:95:14 @@ -580,7 +580,7 @@ error: `$p:path` is followed by `(`, which is not allowed for `path` fragments LL | ($p:path ()) => {}; | ^ not allowed after `path` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$p:path` is followed by `+`, which is not allowed for `path` fragments --> $DIR/macro-follow.rs:97:14 @@ -588,7 +588,7 @@ error: `$p:path` is followed by `+`, which is not allowed for `path` fragments LL | ($p:path +) => {}; | ^ not allowed after `path` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$p:path` is followed by `ident`, which is not allowed for `path` fragments --> $DIR/macro-follow.rs:98:14 @@ -596,7 +596,7 @@ error: `$p:path` is followed by `ident`, which is not allowed for `path` fragmen LL | ($p:path ident) => {}; | ^^^^^ not allowed after `path` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$p:path` is followed by `if`, which is not allowed for `path` fragments --> $DIR/macro-follow.rs:99:14 @@ -604,7 +604,7 @@ error: `$p:path` is followed by `if`, which is not allowed for `path` fragments LL | ($p:path if) => {}; | ^^ not allowed after `path` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$p:path` is followed by `$q:pat`, which is not allowed for `path` fragments --> $DIR/macro-follow.rs:100:14 @@ -612,7 +612,7 @@ error: `$p:path` is followed by `$q:pat`, which is not allowed for `path` fragme LL | ($p:path $q:pat) => {}; | ^^^^^^ not allowed after `path` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$p:path` is followed by `$e:expr`, which is not allowed for `path` fragments --> $DIR/macro-follow.rs:101:14 @@ -620,7 +620,7 @@ error: `$p:path` is followed by `$e:expr`, which is not allowed for `path` fragm LL | ($p:path $e:expr) => {}; | ^^^^^^^ not allowed after `path` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$p:path` is followed by `$t:ty`, which is not allowed for `path` fragments --> $DIR/macro-follow.rs:102:14 @@ -628,7 +628,7 @@ error: `$p:path` is followed by `$t:ty`, which is not allowed for `path` fragmen LL | ($p:path $t:ty) => {}; | ^^^^^ not allowed after `path` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$p:path` is followed by `$s:stmt`, which is not allowed for `path` fragments --> $DIR/macro-follow.rs:103:14 @@ -636,7 +636,7 @@ error: `$p:path` is followed by `$s:stmt`, which is not allowed for `path` fragm LL | ($p:path $s:stmt) => {}; | ^^^^^^^ not allowed after `path` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$p:path` is followed by `$q:path`, which is not allowed for `path` fragments --> $DIR/macro-follow.rs:104:14 @@ -644,7 +644,7 @@ error: `$p:path` is followed by `$q:path`, which is not allowed for `path` fragm LL | ($p:path $q:path) => {}; | ^^^^^^^ not allowed after `path` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$p:path` is followed by `$i:ident`, which is not allowed for `path` fragments --> $DIR/macro-follow.rs:106:14 @@ -652,7 +652,7 @@ error: `$p:path` is followed by `$i:ident`, which is not allowed for `path` frag LL | ($p:path $i:ident) => {}; | ^^^^^^^^ not allowed after `path` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$p:path` is followed by `$t:tt`, which is not allowed for `path` fragments --> $DIR/macro-follow.rs:107:14 @@ -660,7 +660,7 @@ error: `$p:path` is followed by `$t:tt`, which is not allowed for `path` fragmen LL | ($p:path $t:tt) => {}; | ^^^^^ not allowed after `path` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$p:path` is followed by `$i:item`, which is not allowed for `path` fragments --> $DIR/macro-follow.rs:108:14 @@ -668,7 +668,7 @@ error: `$p:path` is followed by `$i:item`, which is not allowed for `path` fragm LL | ($p:path $i:item) => {}; | ^^^^^^^ not allowed after `path` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$p:path` is followed by `$m:meta`, which is not allowed for `path` fragments --> $DIR/macro-follow.rs:109:14 @@ -676,7 +676,7 @@ error: `$p:path` is followed by `$m:meta`, which is not allowed for `path` fragm LL | ($p:path $m:meta) => {}; | ^^^^^^^ not allowed after `path` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: aborting due to 85 previous errors diff --git a/tests/ui/macros/macro-followed-by-seq-bad.stderr b/tests/ui/macros/macro-followed-by-seq-bad.stderr index 7097979aeddf3..d6e11bc7a3eed 100644 --- a/tests/ui/macros/macro-followed-by-seq-bad.stderr +++ b/tests/ui/macros/macro-followed-by-seq-bad.stderr @@ -4,7 +4,7 @@ error: `$a:expr` is followed by `$b:tt`, which is not allowed for `expr` fragmen LL | ( $a:expr $($b:tt)* ) => { }; | ^^^^^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$a:ty` is followed by `$b:tt`, which is not allowed for `ty` fragments --> $DIR/macro-followed-by-seq-bad.rs:8:13 @@ -12,7 +12,7 @@ error: `$a:ty` is followed by `$b:tt`, which is not allowed for `ty` fragments LL | ( $a:ty $($b:tt)* ) => { }; | ^^^^^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: aborting due to 2 previous errors diff --git a/tests/ui/macros/macro-input-future-proofing.stderr b/tests/ui/macros/macro-input-future-proofing.stderr index 542486927dfd1..7c4f6159bb09c 100644 --- a/tests/ui/macros/macro-input-future-proofing.stderr +++ b/tests/ui/macros/macro-input-future-proofing.stderr @@ -4,7 +4,7 @@ error: `$ty:ty` is followed by `<`, which is not allowed for `ty` fragments LL | ($ty:ty <) => (); | ^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$ty:ty` is followed by `<`, which is not allowed for `ty` fragments --> $DIR/macro-input-future-proofing.rs:5:13 @@ -12,7 +12,7 @@ error: `$ty:ty` is followed by `<`, which is not allowed for `ty` fragments LL | ($ty:ty < foo ,) => (); | ^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$pa:pat` is followed by `>`, which is not allowed for `pat` fragments --> $DIR/macro-input-future-proofing.rs:11:14 @@ -20,7 +20,7 @@ error: `$pa:pat` is followed by `>`, which is not allowed for `pat` fragments LL | ($pa:pat >) => (); | ^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$pa:pat` is followed by `$pb:pat`, which is not allowed for `pat` fragments --> $DIR/macro-input-future-proofing.rs:13:14 @@ -28,7 +28,7 @@ error: `$pa:pat` is followed by `$pb:pat`, which is not allowed for `pat` fragme LL | ($pa:pat $pb:pat $ty:ty ,) => (); | ^^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$pb:pat` is followed by `$ty:ty`, which is not allowed for `pat` fragments --> $DIR/macro-input-future-proofing.rs:13:22 @@ -36,7 +36,7 @@ error: `$pb:pat` is followed by `$ty:ty`, which is not allowed for `pat` fragmen LL | ($pa:pat $pb:pat $ty:ty ,) => (); | ^^^^^^ not allowed after `pat` fragments | - = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `|`, `if`, or `in` error: `$ty:ty` is followed by `-`, which is not allowed for `ty` fragments --> $DIR/macro-input-future-proofing.rs:16:17 @@ -44,7 +44,7 @@ error: `$ty:ty` is followed by `-`, which is not allowed for `ty` fragments LL | ($($ty:ty)* -) => (); | ^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$b:ty` is followed by `-`, which is not allowed for `ty` fragments --> $DIR/macro-input-future-proofing.rs:17:23 @@ -52,7 +52,7 @@ error: `$b:ty` is followed by `-`, which is not allowed for `ty` fragments LL | ($($a:ty, $b:ty)* -) => (); | ^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$ty:ty` is followed by `-`, which is not allowed for `ty` fragments --> $DIR/macro-input-future-proofing.rs:18:15 @@ -60,7 +60,7 @@ error: `$ty:ty` is followed by `-`, which is not allowed for `ty` fragments LL | ($($ty:ty)-+) => (); | ^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: `$a:expr` is followed by `$b:tt`, which is not allowed for `expr` fragments --> $DIR/macro-input-future-proofing.rs:19:21 @@ -68,7 +68,7 @@ error: `$a:expr` is followed by `$b:tt`, which is not allowed for `expr` fragmen LL | ( $($a:expr)* $($b:tt)* ) => { }; | ^^^^^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: aborting due to 9 previous errors diff --git a/tests/ui/macros/macro-pat-pattern-followed-by-or-in-2021.stderr b/tests/ui/macros/macro-pat-pattern-followed-by-or-in-2021.stderr index a06487be3d601..378dae941cc62 100644 --- a/tests/ui/macros/macro-pat-pattern-followed-by-or-in-2021.stderr +++ b/tests/ui/macros/macro-pat-pattern-followed-by-or-in-2021.stderr @@ -6,7 +6,7 @@ LL | macro_rules! foo { ($x:pat | $y:pat) => {} } | | | help: try a `pat_param` fragment specifier instead: `$x:pat_param` | - = note: allowed there are: `=>`, `,`, `=`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `if`, or `in` error: `$x:pat` is followed by `|`, which is not allowed for `pat` fragments --> $DIR/macro-pat-pattern-followed-by-or-in-2021.rs:4:32 @@ -16,7 +16,7 @@ LL | macro_rules! bar { ($($x:pat)+ | $($y:pat)+) => {} } | | | help: try a `pat_param` fragment specifier instead: `$x:pat_param` | - = note: allowed there are: `=>`, `,`, `=`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `if`, or `in` error: `$pat:pat` may be followed by `|`, which is not allowed for `pat` fragments --> $DIR/macro-pat-pattern-followed-by-or-in-2021.rs:7:36 @@ -26,7 +26,7 @@ LL | ( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => { | | | help: try a `pat_param` fragment specifier instead: `$pat:pat_param` | - = note: allowed there are: `=>`, `,`, `=`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `if`, or `in` error: aborting due to 3 previous errors diff --git a/tests/ui/macros/macro-pat2021-pattern-followed-by-or.stderr b/tests/ui/macros/macro-pat2021-pattern-followed-by-or.stderr index c3754dde080a3..89ef252576f14 100644 --- a/tests/ui/macros/macro-pat2021-pattern-followed-by-or.stderr +++ b/tests/ui/macros/macro-pat2021-pattern-followed-by-or.stderr @@ -6,7 +6,7 @@ LL | macro_rules! foo { ($x:pat | $y:pat) => {} } | | | help: try a `pat_param` fragment specifier instead: `$x:pat_param` | - = note: allowed there are: `=>`, `,`, `=`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `if`, or `in` error: `$x:pat` is followed by `|`, which is not allowed for `pat` fragments --> $DIR/macro-pat2021-pattern-followed-by-or.rs:7:28 @@ -16,7 +16,7 @@ LL | macro_rules! ogg { ($x:pat | $y:pat_param) => {} } | | | help: try a `pat_param` fragment specifier instead: `$x:pat_param` | - = note: allowed there are: `=>`, `,`, `=`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `if`, or `in` error: `$pat:pat` may be followed by `|`, which is not allowed for `pat` fragments --> $DIR/macro-pat2021-pattern-followed-by-or.rs:9:35 @@ -26,7 +26,7 @@ LL | ( $expr:expr , $( $( $pat:pat)|+ => $expr_arm:pat),+ ) => { | | | help: try a `pat_param` fragment specifier instead: `$pat:pat_param` | - = note: allowed there are: `=>`, `,`, `=`, `if` or `in` + = note: allowed there are: `=>`, `,`, `=`, `if`, or `in` error: aborting due to 3 previous errors diff --git a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr index 8ffda50523584..64cc692222963 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr +++ b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr @@ -3,7 +3,7 @@ error: unexpected token: $ | LL | ( $$ $a:ident ) => { | ^ - + | note: `$$` and meta-variable expressions are not allowed inside macro parameter definitions --> $DIR/syntax-errors.rs:50:8 | @@ -141,7 +141,7 @@ error: unexpected token: { | LL | ( ${ len() } ) => { | ^^^^^^^^^ - + | note: `$$` and meta-variable expressions are not allowed inside macro parameter definitions --> $DIR/syntax-errors.rs:92:8 | diff --git a/tests/ui/macros/same-sequence-span.stderr b/tests/ui/macros/same-sequence-span.stderr index 3242a32e2f4dd..f08a3fa47e3fa 100644 --- a/tests/ui/macros/same-sequence-span.stderr +++ b/tests/ui/macros/same-sequence-span.stderr @@ -4,7 +4,7 @@ error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fra LL | (1 $x:expr $($y:tt,)* | ^^^^^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments --> $DIR/same-sequence-span.rs:15:18 @@ -12,7 +12,7 @@ error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragmen LL | $(= $z:tt)* | ^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments --> $DIR/same-sequence-span.rs:19:1 @@ -26,7 +26,7 @@ LL | proc_macro_sequence::make_foo!(); | _in this macro invocation | | | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` = note: this error originates in the macro `proc_macro_sequence::make_foo` (in Nightly builds, run with -Z macro-backtrace for more info) error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments @@ -35,7 +35,7 @@ error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragmen LL | proc_macro_sequence::make_foo!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments | - = note: allowed there are: `=>`, `,` or `;` + = note: allowed there are: `=>`, `,`, or `;` = note: this error originates in the macro `proc_macro_sequence::make_foo` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/tests/ui/type/pattern_types/macros.active.stderr b/tests/ui/type/pattern_types/macros.active.stderr index 002e944fe2ef3..fd524e73dda26 100644 --- a/tests/ui/type/pattern_types/macros.active.stderr +++ b/tests/ui/type/pattern_types/macros.active.stderr @@ -4,7 +4,7 @@ error: `$t:ty` is followed by `is`, which is not allowed for `ty` fragments LL | ($t:ty is $p:pat) => {}; | ^^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: aborting due to 1 previous error diff --git a/tests/ui/type/pattern_types/macros.gated.stderr b/tests/ui/type/pattern_types/macros.gated.stderr index 002e944fe2ef3..fd524e73dda26 100644 --- a/tests/ui/type/pattern_types/macros.gated.stderr +++ b/tests/ui/type/pattern_types/macros.gated.stderr @@ -4,7 +4,7 @@ error: `$t:ty` is followed by `is`, which is not allowed for `ty` fragments LL | ($t:ty is $p:pat) => {}; | ^^ not allowed after `ty` fragments | - = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where` + = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as`, or `where` error: aborting due to 1 previous error