10641: fix: make `expand_macro` multi-token mapping aware r=spookyvision a=spookyvision



Co-authored-by: Anatol Ulrich <anatol.ulrich@ferrous-systems.com>
Co-authored-by: Anatol Ulrich <45840+spookyvision@users.noreply.github.com>
This commit is contained in:
bors[bot] 2021-10-26 18:18:22 +00:00 committed by GitHub
commit a3830dfd3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -32,19 +32,32 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
_ => 0, _ => 0,
})?; })?;
let descended = sema.descend_into_macros_single(tok.clone()); // due to how Rust Analyzer works internally, we need to special case derive attributes,
if let Some(attr) = descended.ancestors().find_map(ast::Attr::cast) { // otherwise they might not get found, e.g. here with the cursor at $0 `#[attr]` would expand:
if let Some((path, tt)) = attr.as_simple_call() { // ```
if path == "derive" { // #[attr]
let mut tt = tt.syntax().children_with_tokens().skip(1).join(""); // #[derive($0Foo)]
tt.pop(); // struct Bar;
let expansions = sema.expand_derive_macro(&attr)?; // ```
return Some(ExpandedMacro {
name: tt, let derive = sema.descend_into_macros(tok.clone()).iter().find_map(|descended| {
expansion: expansions.into_iter().map(insert_whitespaces).join(""), let attr = descended.ancestors().find_map(ast::Attr::cast)?;
}); let (path, tt) = attr.as_simple_call()?;
} if path == "derive" {
let mut tt = tt.syntax().children_with_tokens().skip(1).join("");
tt.pop();
let expansions = sema.expand_derive_macro(&attr)?;
Some(ExpandedMacro {
name: tt,
expansion: expansions.into_iter().map(insert_whitespaces).join(""),
})
} else {
None
} }
});
if derive.is_some() {
return derive;
} }
// FIXME: Intermix attribute and bang! expansions // FIXME: Intermix attribute and bang! expansions
@ -353,9 +366,12 @@ fn main() {
fn macro_expand_derive() { fn macro_expand_derive() {
check( check(
r#" r#"
//- proc_macros: identity
#[rustc_builtin_macro] #[rustc_builtin_macro]
pub macro Clone {} pub macro Clone {}
#[proc_macros::identity]
#[derive(C$0lone)] #[derive(C$0lone)]
struct Foo {} struct Foo {}
"#, "#,