Skip to content

Commit bc8efca

Browse files
bors[bot]Jonas Schievink
andauthored
Merge #10977
10977: fix: fix `concat!` with captured expression r=jonas-schievink a=jonas-schievink Adds another hack on top of #10623 to fix `concat!`. Fixes #10721 bors r+ Co-authored-by: Jonas Schievink <[email protected]>
2 parents 2534b7d + 95ddeae commit bc8efca

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

crates/hir_def/src/macro_expansion_tests/builtin_fn_macro.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,40 @@ fn main() { "foor0bar\nfalse"; }
313313
);
314314
}
315315

316+
#[test]
317+
fn test_concat_with_captured_expr() {
318+
check(
319+
r##"
320+
#[rustc_builtin_macro]
321+
macro_rules! concat {}
322+
323+
macro_rules! surprise {
324+
() => { "s" };
325+
}
326+
327+
macro_rules! stuff {
328+
($string:expr) => { concat!($string) };
329+
}
330+
331+
fn main() { concat!(surprise!()); }
332+
"##,
333+
expect![[r##"
334+
#[rustc_builtin_macro]
335+
macro_rules! concat {}
336+
337+
macro_rules! surprise {
338+
() => { "s" };
339+
}
340+
341+
macro_rules! stuff {
342+
($string:expr) => { concat!($string) };
343+
}
344+
345+
fn main() { "s"; }
346+
"##]],
347+
);
348+
}
349+
316350
#[test]
317351
fn test_concat_idents_expand() {
318352
check(

crates/hir_expand/src/builtin_fn_macro.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,18 @@ fn concat_expand(
386386
) -> ExpandResult<Option<ExpandedEager>> {
387387
let mut err = None;
388388
let mut text = String::new();
389-
for (i, t) in tt.token_trees.iter().enumerate() {
389+
for (i, mut t) in tt.token_trees.iter().enumerate() {
390+
// FIXME: hack on top of a hack: `$e:expr` captures get surrounded in parentheses
391+
// to ensure the right parsing order, so skip the parentheses here. Ideally we'd
392+
// implement rustc's model. cc https://github.com/rust-analyzer/rust-analyzer/pull/10623
393+
if let tt::TokenTree::Subtree(tt::Subtree { delimiter: Some(delim), token_trees }) = t {
394+
if let [tt] = &**token_trees {
395+
if delim.kind == tt::DelimiterKind::Parenthesis {
396+
t = tt;
397+
}
398+
}
399+
}
400+
390401
match t {
391402
tt::TokenTree::Leaf(tt::Leaf::Literal(it)) if i % 2 == 0 => {
392403
// concat works with string and char literals, so remove any quotes.

0 commit comments

Comments
 (0)