More detail when expecting expression but encountering bad macro argument
Partially address #71039.
This commit is contained in:
parent
1be1e84872
commit
4e418805da
27 changed files with 200 additions and 67 deletions
|
@ -67,6 +67,12 @@ pub(super) fn failed_to_match_macro<'cx>(
|
|||
&& (matches!(expected_token.kind, TokenKind::Interpolated(_))
|
||||
|| matches!(token.kind, TokenKind::Interpolated(_)))
|
||||
{
|
||||
if let TokenKind::Interpolated(node) = &expected_token.kind {
|
||||
err.span_label(node.1, "");
|
||||
}
|
||||
if let TokenKind::Interpolated(node) = &token.kind {
|
||||
err.span_label(node.1, "");
|
||||
}
|
||||
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");
|
||||
|
||||
|
|
|
@ -397,7 +397,7 @@ pub(crate) enum NamedMatch {
|
|||
MatchedTokenTree(rustc_ast::tokenstream::TokenTree),
|
||||
|
||||
// A metavar match of any type other than `tt`.
|
||||
MatchedNonterminal(Lrc<Nonterminal>),
|
||||
MatchedNonterminal(Lrc<(Nonterminal, rustc_span::Span)>),
|
||||
}
|
||||
|
||||
/// Performs a token equality check, ignoring syntax context (that is, an unhygienic comparison)
|
||||
|
@ -692,7 +692,7 @@ impl TtParser {
|
|||
Ok(nt) => nt,
|
||||
};
|
||||
let m = match nt {
|
||||
ParseNtResult::Nt(nt) => MatchedNonterminal(Lrc::new(nt)),
|
||||
ParseNtResult::Nt(nt) => MatchedNonterminal(Lrc::new((nt, span))),
|
||||
ParseNtResult::Tt(tt) => MatchedTokenTree(tt),
|
||||
};
|
||||
mp.push_match(next_metavar, seq_depth, m);
|
||||
|
|
|
@ -126,7 +126,7 @@ impl MultiItemModifier for DeriveProcMacro {
|
|||
Annotatable::Stmt(stmt) => token::NtStmt(stmt),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
TokenStream::token_alone(token::Interpolated(Lrc::new(nt)), DUMMY_SP)
|
||||
TokenStream::token_alone(token::Interpolated(Lrc::new((nt, span))), DUMMY_SP)
|
||||
} else {
|
||||
item.to_tokens()
|
||||
};
|
||||
|
|
|
@ -226,18 +226,23 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
|
|||
}));
|
||||
}
|
||||
|
||||
Interpolated(nt) if let NtIdent(ident, is_raw) = *nt => trees
|
||||
.push(TokenTree::Ident(Ident { sym: ident.name, is_raw, span: ident.span })),
|
||||
Interpolated(ref nt) if let NtIdent(ident, is_raw) = &nt.0 => {
|
||||
trees.push(TokenTree::Ident(Ident {
|
||||
sym: ident.name,
|
||||
is_raw: *is_raw,
|
||||
span: ident.span,
|
||||
}))
|
||||
}
|
||||
|
||||
Interpolated(nt) => {
|
||||
let stream = TokenStream::from_nonterminal_ast(&nt);
|
||||
let stream = TokenStream::from_nonterminal_ast(&nt.0);
|
||||
// A hack used to pass AST fragments to attribute and derive
|
||||
// macros as a single nonterminal token instead of a token
|
||||
// stream. Such token needs to be "unwrapped" and not
|
||||
// represented as a delimited group.
|
||||
// FIXME: It needs to be removed, but there are some
|
||||
// compatibility issues (see #73345).
|
||||
if crate::base::nt_pretty_printing_compatibility_hack(&nt, rustc.sess()) {
|
||||
if crate::base::nt_pretty_printing_compatibility_hack(&nt.0, rustc.sess()) {
|
||||
trees.extend(Self::from_internal((stream, rustc)));
|
||||
} else {
|
||||
trees.push(TokenTree::Group(Group {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue