Fix concat! with integer literals

This commit is contained in:
Jonas Schievink 2020-12-08 20:06:41 +01:00
parent 70fa57f8d3
commit bb28aef918

View file

@ -287,23 +287,34 @@ fn concat_expand(
_arg_id: EagerMacroId, _arg_id: EagerMacroId,
tt: &tt::Subtree, tt: &tt::Subtree,
) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { ) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
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, t) in tt.token_trees.iter().enumerate() {
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 => {
text += &match unquote_str(&it) { // concat works with string and char literals, so remove any quotes.
Some(s) => s, // It also works with integer, float and boolean literals, so just use the rest
None => { // as-is.
return ExpandResult::only_err(mbe::ExpandError::ConversionError);
} text += it
}; .text
.trim_start_matches(|c| match c {
'r' | '#' | '\'' | '"' => true,
_ => false,
})
.trim_end_matches(|c| match c {
'#' | '\'' | '"' => true,
_ => false,
});
} }
tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if i % 2 == 1 && punct.char == ',' => (), tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if i % 2 == 1 && punct.char == ',' => (),
_ => return ExpandResult::only_err(mbe::ExpandError::UnexpectedToken), _ => {
err.get_or_insert(mbe::ExpandError::UnexpectedToken);
}
} }
} }
ExpandResult::ok(Some((quote!(#text), FragmentKind::Expr))) ExpandResult { value: Some((quote!(#text), FragmentKind::Expr)), err }
} }
fn relative_file( fn relative_file(
@ -686,4 +697,19 @@ mod tests {
assert_eq!(expanded, r#"b"""#); assert_eq!(expanded, r#"b"""#);
} }
#[test]
fn test_concat_expand() {
let expanded = expand_builtin_macro(
r##"
#[rustc_builtin_macro]
macro_rules! concat {}
concat!("foo", 0, r#"bar"#);
"##,
);
assert_eq!(expanded, r#""foo0bar""#);
// FIXME: `true`/`false` literals don't work.
}
} }