about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNilstrieb <48135649+Nilstrieb@users.noreply.github.com>2023-03-03 20:37:51 +0000
committerNilstrieb <48135649+Nilstrieb@users.noreply.github.com>2023-03-10 16:59:26 +0000
commit3dee4630ba1fe9de0aa03e920dfe993a6d357945 (patch)
tree9cfc6e9c3ac1907d25851f46670aad77e9b2046f
parentd5833423a02e2373c5e3cceb238fb19192cd82f8 (diff)
downloadrust-3dee4630ba1fe9de0aa03e920dfe993a6d357945.tar.gz
rust-3dee4630ba1fe9de0aa03e920dfe993a6d357945.zip
Add note when matching token with nonterminal
The current error message is _really_ confusing.
-rw-r--r--compiler/rustc_expand/src/mbe/diagnostics.rs12
-rw-r--r--tests/ui/macros/nonterminal-matching.stderr1
2 files changed, 10 insertions, 3 deletions
diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs
index f469b2daef5..b1d9cea2773 100644
--- a/compiler/rustc_expand/src/mbe/diagnostics.rs
+++ b/compiler/rustc_expand/src/mbe/diagnostics.rs
@@ -1,12 +1,10 @@
-use std::borrow::Cow;
-
 use crate::base::{DummyResult, ExtCtxt, MacResult};
 use crate::expand::{parse_ast_fragment, AstFragmentKind};
 use crate::mbe::{
     macro_parser::{MatcherLoc, NamedParseResult, ParseResult::*, TtParser},
     macro_rules::{try_match_macro, Tracker},
 };
-use rustc_ast::token::{self, Token};
+use rustc_ast::token::{self, Token, TokenKind};
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast_pretty::pprust;
 use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage};
@@ -14,6 +12,7 @@ use rustc_parse::parser::{Parser, Recovery};
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::Ident;
 use rustc_span::Span;
+use std::borrow::Cow;
 
 use super::macro_rules::{parser_from_cx, NoopTracker};
 
@@ -63,6 +62,13 @@ pub(super) fn failed_to_match_macro<'cx>(
         err.note(format!("while trying to match {remaining_matcher}"));
     }
 
+    if let MatcherLoc::Token { token: expected_token } = &remaining_matcher
+        && (matches!(expected_token.kind, TokenKind::Interpolated(_))
+            || matches!(token.kind, TokenKind::Interpolated(_)))
+    {
+        err.note("captured metavariables except for `$tt`, `$ident` and `$lifetime` cannot be compared to other tokens");
+    }
+
     // Check whether there's a missing comma in this macro call, like `println!("{}" a);`
     if let Some((arg, comma_span)) = arg.add_comma() {
         for lhs in lhses {
diff --git a/tests/ui/macros/nonterminal-matching.stderr b/tests/ui/macros/nonterminal-matching.stderr
index 5bbd5439098..762ecc3207f 100644
--- a/tests/ui/macros/nonterminal-matching.stderr
+++ b/tests/ui/macros/nonterminal-matching.stderr
@@ -18,6 +18,7 @@ LL |     macro n(a $nt_item b) {
 ...
 LL | complex_nonterminal!(enum E {});
    | ------------------------------- in this macro invocation
+   = note: captured metavariables except for `$tt`, `$ident` and `$lifetime` cannot be compared to other tokens
    = note: this error originates in the macro `complex_nonterminal` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error