10977: fix: fix `concat!` with captured expression r=jonas-schievink a=jonas-schievink

Adds another hack on top of https://github.com/rust-analyzer/rust-analyzer/pull/10623 to fix `concat!`.

Fixes https://github.com/rust-analyzer/rust-analyzer/issues/10721

bors r+

Co-authored-by: Jonas Schievink <jonas.schievink@ferrous-systems.com>
This commit is contained in:
bors[bot] 2021-12-10 14:19:51 +00:00 committed by GitHub
commit bc8efca0c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 1 deletions

View File

@ -313,6 +313,40 @@ macro_rules! concat {}
); );
} }
#[test]
fn test_concat_with_captured_expr() {
check(
r##"
#[rustc_builtin_macro]
macro_rules! concat {}
macro_rules! surprise {
() => { "s" };
}
macro_rules! stuff {
($string:expr) => { concat!($string) };
}
fn main() { concat!(surprise!()); }
"##,
expect![[r##"
#[rustc_builtin_macro]
macro_rules! concat {}
macro_rules! surprise {
() => { "s" };
}
macro_rules! stuff {
($string:expr) => { concat!($string) };
}
fn main() { "s"; }
"##]],
);
}
#[test] #[test]
fn test_concat_idents_expand() { fn test_concat_idents_expand() {
check( check(

View File

@ -386,7 +386,18 @@ fn concat_expand(
) -> ExpandResult<Option<ExpandedEager>> { ) -> ExpandResult<Option<ExpandedEager>> {
let mut err = None; let mut err = None;
let mut text = String::new(); let mut text = String::new();
for (i, t) in tt.token_trees.iter().enumerate() { for (i, mut t) in tt.token_trees.iter().enumerate() {
// FIXME: hack on top of a hack: `$e:expr` captures get surrounded in parentheses
// to ensure the right parsing order, so skip the parentheses here. Ideally we'd
// implement rustc's model. cc https://github.com/rust-analyzer/rust-analyzer/pull/10623
if let tt::TokenTree::Subtree(tt::Subtree { delimiter: Some(delim), token_trees }) = t {
if let [tt] = &**token_trees {
if delim.kind == tt::DelimiterKind::Parenthesis {
t = tt;
}
}
}
match t { match t {
tt::TokenTree::Leaf(tt::Leaf::Literal(it)) if i % 2 == 0 => { tt::TokenTree::Leaf(tt::Leaf::Literal(it)) if i % 2 == 0 => {
// concat works with string and char literals, so remove any quotes. // concat works with string and char literals, so remove any quotes.