8808: fix: Fix fn proc macro input again r=jonas-schievink a=jonas-schievink

https://github.com/rust-analyzer/rust-analyzer/pull/8806 broke the `TokenMap`, so none of the tokens in fn-like proc macro inputs could be related to the output (presumably this is because of the `clone_for_update`).

This PR instead just sets `delimiter = None;` after the `TokenMap` and `Subtree` are already created.

We should probably have more tests for fn-like proc macros, and consider making the behavior consistent with MBE (which *require* the delimiters to be present).

bors r+

Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
This commit is contained in:
bors[bot] 2021-05-11 23:05:07 +00:00 committed by GitHub
commit 9a431c26f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 12 additions and 30 deletions

View file

@ -267,7 +267,16 @@ fn parse_macro_expansion(
fn macro_arg(db: &dyn AstDatabase, id: MacroCallId) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>> {
let arg = db.macro_arg_text(id)?;
let (tt, tmap) = mbe::syntax_node_to_token_tree(&SyntaxNode::new_root(arg));
let (mut tt, tmap) = mbe::syntax_node_to_token_tree(&SyntaxNode::new_root(arg));
if let MacroCallId::LazyMacro(id) = id {
let loc: MacroCallLoc = db.lookup_intern_macro(id);
if loc.def.is_proc_macro() {
// proc macros expect their inputs without parentheses, MBEs expect it with them included
tt.delimiter = None;
}
}
Some(Arc::new((tt, tmap)))
}

View file

@ -1,9 +1,8 @@
//! Macro input conditioning.
use parser::SyntaxKind;
use syntax::{
ast::{self, AttrsOwner},
AstNode, SyntaxElement, SyntaxNode,
AstNode, SyntaxNode,
};
use crate::{
@ -20,33 +19,7 @@ pub(crate) fn process_macro_input(
let loc: MacroCallLoc = db.lookup_intern_macro(id);
match loc.kind {
MacroCallKind::FnLike { .. } => {
if !loc.def.is_proc_macro() {
// MBE macros expect the parentheses as part of their input.
return node;
}
// The input includes the `(` + `)` delimiter tokens, so remove them before passing this
// to the macro.
let node = node.clone_for_update();
if let Some(SyntaxElement::Token(tkn)) = node.first_child_or_token() {
if matches!(
tkn.kind(),
SyntaxKind::L_BRACK | SyntaxKind::L_PAREN | SyntaxKind::L_CURLY
) {
tkn.detach();
}
}
if let Some(SyntaxElement::Token(tkn)) = node.last_child_or_token() {
if matches!(
tkn.kind(),
SyntaxKind::R_BRACK | SyntaxKind::R_PAREN | SyntaxKind::R_CURLY
) {
tkn.detach();
}
}
node
}
MacroCallKind::FnLike { .. } => node,
MacroCallKind::Derive { derive_attr_index, .. } => {
let item = match ast::Item::cast(node.clone()) {
Some(item) => item,