Skip to content

Commit fa759f7

Browse files
authored
Merge pull request #19434 from vishruth-thimmaiah/negatives_in_concat
fix: negative nums in `concat!` expansion
2 parents fdfa707 + 109d933 commit fa759f7

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -454,13 +454,13 @@ fn test_concat_expand() {
454454
#[rustc_builtin_macro]
455455
macro_rules! concat {}
456456
457-
fn main() { concat!("fo", "o", 0, r#""bar""#, "\n", false, '"', '\0'); }
457+
fn main() { concat!("fo", "o", 0, r#""bar""#, "\n", false, '"', -4, - 4, '\0'); }
458458
"##,
459459
expect![[r##"
460460
#[rustc_builtin_macro]
461461
macro_rules! concat {}
462462
463-
fn main() { "foo0\"bar\"\nfalse\"\u{0}"; }
463+
fn main() { "foo0\"bar\"\nfalse\"-4-4\u{0}"; }
464464
"##]],
465465
);
466466
}

crates/hir-expand/src/builtin/fn_macro.rs

+34-1
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,10 @@ fn concat_expand(
452452
Some(_) => (),
453453
None => span = Some(s),
454454
};
455-
for (i, mut t) in tt.iter().enumerate() {
455+
456+
let mut i = 0;
457+
let mut iter = tt.iter();
458+
while let Some(mut t) = iter.next() {
456459
// FIXME: hack on top of a hack: `$e:expr` captures get surrounded in parentheses
457460
// to ensure the right parsing order, so skip the parentheses here. Ideally we'd
458461
// implement rustc's model. cc https://github.com/rust-lang/rust-analyzer/pull/10623
@@ -504,10 +507,40 @@ fn concat_expand(
504507
record_span(id.span);
505508
}
506509
TtElement::Leaf(tt::Leaf::Punct(punct)) if i % 2 == 1 && punct.char == ',' => (),
510+
// handle negative numbers
511+
TtElement::Leaf(tt::Leaf::Punct(punct)) if i % 2 == 0 && punct.char == '-' => {
512+
let t = match iter.next() {
513+
Some(t) => t,
514+
None => {
515+
err.get_or_insert(ExpandError::other(
516+
call_site,
517+
"unexpected end of input after '-'",
518+
));
519+
break;
520+
}
521+
};
522+
523+
match t {
524+
TtElement::Leaf(tt::Leaf::Literal(it))
525+
if matches!(it.kind, tt::LitKind::Integer | tt::LitKind::Float) =>
526+
{
527+
format_to!(text, "-{}", it.symbol.as_str());
528+
record_span(punct.span.cover(it.span));
529+
}
530+
_ => {
531+
err.get_or_insert(ExpandError::other(
532+
call_site,
533+
"expected integer or floating pointer number after '-'",
534+
));
535+
break;
536+
}
537+
}
538+
}
507539
_ => {
508540
err.get_or_insert(ExpandError::other(call_site, "unexpected token"));
509541
}
510542
}
543+
i += 1;
511544
}
512545
let span = span.unwrap_or_else(|| tt.top_subtree().delimiter.open);
513546
ExpandResult { value: quote!(span =>#text), err }

0 commit comments

Comments
 (0)