diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 12f308fc546c3..e5369c44efcf4 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -13,7 +13,7 @@ use rustc_ast_pretty::pprust; use rustc_attr_ir::diagnostic::Directive; use rustc_attr_ir::{self as attrs, find_attr}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; -use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan}; +use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, StringPart}; use rustc_feature::Features; use rustc_hir::def::MacroKinds; use rustc_lint_defs::builtin::{ @@ -1643,21 +1643,32 @@ fn check_matcher_core<'tt>( ); } - let msg = "allowed there are: "; match possible { &[] => {} &[t] => { - err.note(format!( - "only {t} is allowed after `{kind}` fragments", - )); + err.highlighted_note(vec![ + StringPart::normal("only "), + StringPart::highlighted(t), + StringPart::normal(format!( + " is allowed after `{kind}` fragments" + )), + ]); } ts => { - err.note(format!( - "{}{} or {}", - msg, - ts[..ts.len() - 1].to_vec().join(", "), - ts[ts.len() - 1], - )); + let mut msg_parts = + vec![StringPart::normal("allowed there are: ")]; + + for (i, &t) in ts.iter().enumerate() { + if i == ts.len() - 1 { + msg_parts.push(StringPart::normal(" or ")); + } else if i > 0 { + msg_parts.push(StringPart::normal(", ")); + } + + msg_parts.push(StringPart::highlighted(t)); + } + + err.highlighted_note(msg_parts); } } errored = Err(err.emit_err()); diff --git a/tests/ui/macros/highlight-symbols-after-fragment-issue-156458.rs b/tests/ui/macros/highlight-symbols-after-fragment-issue-156458.rs new file mode 100644 index 0000000000000..98de393cc81aa --- /dev/null +++ b/tests/ui/macros/highlight-symbols-after-fragment-issue-156458.rs @@ -0,0 +1,12 @@ +// Make sure accepted characters in the macro syntax warning message is highlighted in magenta. + +//@ compile-flags: --error-format=human --color=always +//@ edition:2018 + +macro_rules! m { + ($e:expr ~ $id:ident) => {}; +} + +fn main() {} + +//~? RAW `=>`, `,` or `;` diff --git a/tests/ui/macros/highlight-symbols-after-fragment-issue-156458.svg b/tests/ui/macros/highlight-symbols-after-fragment-issue-156458.svg new file mode 100644 index 0000000000000..9b665a1c45aea --- /dev/null +++ b/tests/ui/macros/highlight-symbols-after-fragment-issue-156458.svg @@ -0,0 +1,47 @@ + + + + + + + error: `$e:expr` is followed by `~`, which is not allowed for `expr` fragments + + --> $DIR/highlight-symbols-after-fragment-issue-156458.rs:7:14 + + | + + LL | ($e:expr ~ $id:ident) => {}; + + | ^ not allowed after `expr` fragments + + | + + = note: allowed there are: `=>`, `,` or `;` + + + + error: aborting due to 1 previous error + + + + + + + + diff --git a/tests/ui/macros/highlight-symbols-after-fragment-issue-156458.windows.svg b/tests/ui/macros/highlight-symbols-after-fragment-issue-156458.windows.svg new file mode 100644 index 0000000000000..346ed3b294c2e --- /dev/null +++ b/tests/ui/macros/highlight-symbols-after-fragment-issue-156458.windows.svg @@ -0,0 +1,48 @@ + + + + + + + error: `$e:expr` is followed by `~`, which is not allowed for `expr` fragments + + --> $DIR/highlight-symbols-after-fragment-issue-156458.rs:7:14 + + | + + LL | ($e:expr ~ $id:ident) => {}; + + | ^ not allowed after `expr` fragments + + | + + = note: allowed there are: `=>`, `,` or `;` + + + + error: aborting due to 1 previous error + + + + + + + +