summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_expand/src/mbe/diagnostics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_expand/src/mbe/diagnostics.rs')
-rw-r--r--compiler/rustc_expand/src/mbe/diagnostics.rs41
1 files changed, 32 insertions, 9 deletions
diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs
index f469b2dae..355722922 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,18 @@ 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");
+ err.note("see <https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment> for more information");
+
+ if !def_span.is_dummy() && !cx.source_map().is_imported(def_span) {
+ err.help("try using `:tt` instead in the macro definition");
+ }
+ }
+
// 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 {
@@ -239,12 +250,24 @@ pub(super) fn emit_frag_parse_err(
e.note(
"the macro call doesn't expand to an expression, but it can expand to a statement",
);
- e.span_suggestion_verbose(
- site_span.shrink_to_hi(),
- "add `;` to interpret the expansion as a statement",
- ";",
- Applicability::MaybeIncorrect,
- );
+
+ if parser.token == token::Semi {
+ if let Ok(snippet) = parser.sess.source_map().span_to_snippet(site_span) {
+ e.span_suggestion_verbose(
+ site_span,
+ "surround the macro invocation with `{}` to interpret the expansion as a statement",
+ format!("{{ {}; }}", snippet),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ } else {
+ e.span_suggestion_verbose(
+ site_span.shrink_to_hi(),
+ "add `;` to interpret the expansion as a statement",
+ ";",
+ Applicability::MaybeIncorrect,
+ );
+ }
}
},
_ => annotate_err_with_kind(&mut e, kind, site_span),