Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #12942 - lowr:fix/concat-with-char, r=Veykril
fix: make `concat!` work with char Fixes #12921 - I avoided making `unquote_str()` take char literals as well because it's depended on by another function `parse_string()` that's only supposed to take strings. - Even with this patch, we don't output `\0` as `\u{0}` which #12921 pointed out ~~, but we're not actually responsible for serializing it but rowan is~~. They are functionally equivalent and I don't think it'd cause any confusion, but we *could* try escaping them before serialization (for reference, `rustc -Zunpretty=expanded`, which `cargo expand` uses under the hood, [makes use of `str::escape_default()`](https://github.com/rust-lang/rust/blob/3830ecaa8db798d2727cbdfa4ddf314ff938f268/compiler/rustc_ast/src/util/literal.rs#L161).
bors 2022-08-08
parent 634cfe3 · parent 4d5873e · commit b569bbb
-rw-r--r--crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs4
-rw-r--r--crates/hir-expand/src/builtin_fn_macro.rs14
-rw-r--r--crates/hir-expand/src/quote.rs4
3 files changed, 16 insertions, 6 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..4f626105a5 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, '"', '\0'); }
"##,
expect![[r##"
#[rustc_builtin_macro]
macro_rules! concat {}
-fn main() { "foor0bar\nfalse"; }
+fn main() { "foor0bar\nfalse\"\u{0}"; }
"##]],
);
}
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<String> {
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>> {
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))
diff --git a/crates/hir-expand/src/quote.rs b/crates/hir-expand/src/quote.rs
index 82f410ecda..e839e97bf0 100644
--- a/crates/hir-expand/src/quote.rs
+++ b/crates/hir-expand/src/quote.rs
@@ -196,8 +196,8 @@ impl_to_to_tokentrees! {
tt::Literal => self { self };
tt::Ident => self { self };
tt::Punct => self { self };
- &str => self { tt::Literal{text: format!("\"{}\"", self.escape_debug()).into(), id: tt::TokenId::unspecified()}};
- String => self { tt::Literal{text: format!("\"{}\"", self.escape_debug()).into(), id: tt::TokenId::unspecified()}}
+ &str => self { tt::Literal{text: format!("\"{}\"", self.escape_default()).into(), id: tt::TokenId::unspecified()}};
+ String => self { tt::Literal{text: format!("\"{}\"", self.escape_default()).into(), id: tt::TokenId::unspecified()}}
}
#[cfg(test)]