Skip to content

Commit 0e2b1b7

Browse files
Merge #6768
6768: Fix `concat!` with integer literals r=jonas-schievink a=jonas-schievink Addresses #6747 (comment) bors r+ Co-authored-by: Jonas Schievink <[email protected]>
2 parents 9145b97 + bb28aef commit 0e2b1b7

File tree

1 file changed

+34
-8
lines changed

1 file changed

+34
-8
lines changed

crates/hir_expand/src/builtin_macro.rs

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -287,23 +287,34 @@ fn concat_expand(
287287
_arg_id: EagerMacroId,
288288
tt: &tt::Subtree,
289289
) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
290+
let mut err = None;
290291
let mut text = String::new();
291292
for (i, t) in tt.token_trees.iter().enumerate() {
292293
match t {
293294
tt::TokenTree::Leaf(tt::Leaf::Literal(it)) if i % 2 == 0 => {
294-
text += &match unquote_str(&it) {
295-
Some(s) => s,
296-
None => {
297-
return ExpandResult::only_err(mbe::ExpandError::ConversionError);
298-
}
299-
};
295+
// concat works with string and char literals, so remove any quotes.
296+
// It also works with integer, float and boolean literals, so just use the rest
297+
// as-is.
298+
299+
text += it
300+
.text
301+
.trim_start_matches(|c| match c {
302+
'r' | '#' | '\'' | '"' => true,
303+
_ => false,
304+
})
305+
.trim_end_matches(|c| match c {
306+
'#' | '\'' | '"' => true,
307+
_ => false,
308+
});
300309
}
301310
tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if i % 2 == 1 && punct.char == ',' => (),
302-
_ => return ExpandResult::only_err(mbe::ExpandError::UnexpectedToken),
311+
_ => {
312+
err.get_or_insert(mbe::ExpandError::UnexpectedToken);
313+
}
303314
}
304315
}
305316

306-
ExpandResult::ok(Some((quote!(#text), FragmentKind::Expr)))
317+
ExpandResult { value: Some((quote!(#text), FragmentKind::Expr)), err }
307318
}
308319

309320
fn relative_file(
@@ -686,4 +697,19 @@ mod tests {
686697

687698
assert_eq!(expanded, r#"b"""#);
688699
}
700+
701+
#[test]
702+
fn test_concat_expand() {
703+
let expanded = expand_builtin_macro(
704+
r##"
705+
#[rustc_builtin_macro]
706+
macro_rules! concat {}
707+
concat!("foo", 0, r#"bar"#);
708+
"##,
709+
);
710+
711+
assert_eq!(expanded, r#""foo0bar""#);
712+
713+
// FIXME: `true`/`false` literals don't work.
714+
}
689715
}

0 commit comments

Comments
 (0)