fix: make concat! work with char

This commit is contained in:
Ryo Yoshida 2022-08-05 02:51:38 +09:00
parent 1c03f45c08
commit 859d467276
No known key found for this signature in database
GPG Key ID: E25698A930586171
2 changed files with 14 additions and 4 deletions

View File

@ -295,13 +295,13 @@ fn test_concat_expand() {
#[rustc_builtin_macro] #[rustc_builtin_macro]
macro_rules! concat {} macro_rules! concat {}
fn main() { concat!("foo", "r", 0, r#"bar"#, "\n", false); } fn main() { concat!("foo", "r", 0, r#"bar"#, "\n", false, '\n'); }
"##, "##,
expect![[r##" expect![[r##"
#[rustc_builtin_macro] #[rustc_builtin_macro]
macro_rules! concat {} macro_rules! concat {}
fn main() { "foor0bar\nfalse"; } fn main() { "foor0bar\nfalse\n"; }
"##]], "##]],
); );
} }

View File

@ -357,6 +357,12 @@ fn unquote_str(lit: &tt::Literal) -> Option<String> {
token.value().map(|it| it.into_owned()) token.value().map(|it| it.into_owned())
} }
fn unquote_char(lit: &tt::Literal) -> Option<char> {
let lit = ast::make::tokens::literal(&lit.to_string());
let token = ast::Char::cast(lit)?;
token.value()
}
fn unquote_byte_string(lit: &tt::Literal) -> Option<Vec<u8>> { fn unquote_byte_string(lit: &tt::Literal) -> Option<Vec<u8>> {
let lit = ast::make::tokens::literal(&lit.to_string()); let lit = ast::make::tokens::literal(&lit.to_string());
let token = ast::ByteString::cast(lit)?; let token = ast::ByteString::cast(lit)?;
@ -408,8 +414,12 @@ fn concat_expand(
// concat works with string and char literals, so remove any quotes. // concat works with string and char literals, so remove any quotes.
// It also works with integer, float and boolean literals, so just use the rest // It also works with integer, float and boolean literals, so just use the rest
// as-is. // as-is.
let component = unquote_str(it).unwrap_or_else(|| it.text.to_string()); if let Some(c) = unquote_char(it) {
text.push_str(&component); text.push(c);
} else {
let component = unquote_str(it).unwrap_or_else(|| it.text.to_string());
text.push_str(&component);
}
} }
// handle boolean literals // handle boolean literals
tt::TokenTree::Leaf(tt::Leaf::Ident(id)) tt::TokenTree::Leaf(tt::Leaf::Ident(id))