From 859d467276bf45e621858069192d7a68c42d2a32 Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Fri, 5 Aug 2022 02:51:38 +0900 Subject: [PATCH] fix: make `concat!` work with char --- .../src/macro_expansion_tests/builtin_fn_macro.rs | 4 ++-- crates/hir-expand/src/builtin_fn_macro.rs | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs b/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs index 92dffa7f37..32006c4b43 100644 --- a/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs +++ b/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs @@ -295,13 +295,13 @@ fn test_concat_expand() { #[rustc_builtin_macro] 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##" #[rustc_builtin_macro] macro_rules! concat {} -fn main() { "foor0bar\nfalse"; } +fn main() { "foor0bar\nfalse\n"; } "##]], ); } diff --git a/crates/hir-expand/src/builtin_fn_macro.rs b/crates/hir-expand/src/builtin_fn_macro.rs index 76da7c9f1e..c21b35cdc0 100644 --- a/crates/hir-expand/src/builtin_fn_macro.rs +++ b/crates/hir-expand/src/builtin_fn_macro.rs @@ -357,6 +357,12 @@ fn unquote_str(lit: &tt::Literal) -> Option { token.value().map(|it| it.into_owned()) } +fn unquote_char(lit: &tt::Literal) -> Option { + 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> { let lit = ast::make::tokens::literal(&lit.to_string()); let token = ast::ByteString::cast(lit)?; @@ -408,8 +414,12 @@ fn concat_expand( // 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 // as-is. - let component = unquote_str(it).unwrap_or_else(|| it.text.to_string()); - text.push_str(&component); + if let Some(c) = unquote_char(it) { + text.push(c); + } else { + let component = unquote_str(it).unwrap_or_else(|| it.text.to_string()); + text.push_str(&component); + } } // handle boolean literals tt::TokenTree::Leaf(tt::Leaf::Ident(id))