diff options
| author | hkalbasi <hamidrezakalbasi@protonmail.com> | 2023-05-18 12:32:41 +0330 |
|---|---|---|
| committer | hkalbasi <hamidrezakalbasi@protonmail.com> | 2023-05-18 12:32:41 +0330 |
| commit | 5c83e222a3e001488a313e84a3e584ac0c773d8a (patch) | |
| tree | cb8f608e2a9342e7e7b13c21290eedb6758c9f7d | |
| parent | a2fba7c67ec46afc78701759719ffabf4218ad3d (diff) | |
| download | rust-5c83e222a3e001488a313e84a3e584ac0c773d8a.tar.gz rust-5c83e222a3e001488a313e84a3e584ac0c773d8a.zip | |
fix `format_args` expansion error with raw strings
| -rw-r--r-- | crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs | 33 | ||||
| -rw-r--r-- | crates/hir-expand/src/builtin_fn_macro.rs | 26 |
2 files changed, 54 insertions, 5 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 0beab57eb73..f5346898c20 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 @@ -236,6 +236,39 @@ fn main() { } #[test] +fn test_format_args_expand_with_raw_strings() { + check( + r##" +#[rustc_builtin_macro] +macro_rules! format_args { + ($fmt:expr) => ({ /* compiler built-in */ }); + ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }) +} + +fn main() { + format_args!( + r#"{},mismatch,"{}","{}""#, + location_csv_pat(db, &analysis, vfs, &sm, pat_id), + mismatch.expected.display(db), + mismatch.actual.display(db) + ); +} +"##, + expect![[r##" +#[rustc_builtin_macro] +macro_rules! format_args { + ($fmt:expr) => ({ /* compiler built-in */ }); + ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }) +} + +fn main() { + $crate::fmt::Arguments::new_v1(&[r#""#, r#",mismatch,""#, r#"",""#, r#"""#, ], &[$crate::fmt::ArgumentV1::new(&(location_csv_pat(db, &analysis, vfs, &sm, pat_id)), $crate::fmt::Display::fmt), $crate::fmt::ArgumentV1::new(&(mismatch.expected.display(db)), $crate::fmt::Display::fmt), $crate::fmt::ArgumentV1::new(&(mismatch.actual.display(db)), $crate::fmt::Display::fmt), ]); +} +"##]], + ); +} + +#[test] fn test_format_args_expand_eager() { check( r#" diff --git a/crates/hir-expand/src/builtin_fn_macro.rs b/crates/hir-expand/src/builtin_fn_macro.rs index 3f9ea96545c..e9e1c6c3b33 100644 --- a/crates/hir-expand/src/builtin_fn_macro.rs +++ b/crates/hir-expand/src/builtin_fn_macro.rs @@ -287,16 +287,27 @@ fn format_args_expand_general( match token_tree { tt::TokenTree::Leaf(l) => match l { tt::Leaf::Literal(l) => { - let text = l.text.strip_prefix('"')?.strip_suffix('"')?; - let span = l.span; - Some((text, span)) + if let Some(mut text) = l.text.strip_prefix('r') { + let mut raw_sharps = String::new(); + while let Some(t) = text.strip_prefix('#') { + text = t; + raw_sharps.push('#'); + } + text = + text.strip_suffix(&raw_sharps)?.strip_prefix('"')?.strip_suffix('"')?; + Some((text, l.span, Some(raw_sharps))) + } else { + let text = l.text.strip_prefix('"')?.strip_suffix('"')?; + let span = l.span; + Some((text, span, None)) + } } _ => None, }, tt::TokenTree::Subtree(_) => None, } })(); - let Some((format_string, _format_string_span)) = format_string else { + let Some((format_string, _format_string_span, raw_sharps)) = format_string else { return expand_error; }; let mut format_iter = format_string.chars().peekable(); @@ -379,7 +390,12 @@ fn format_args_expand_general( parts.push(last_part); } let part_tts = parts.into_iter().map(|x| { - let l = tt::Literal { span: tt::TokenId::unspecified(), text: format!("\"{}\"", x).into() }; + let text = if let Some(raw) = &raw_sharps { + format!("r{raw}\"{}\"{raw}", x).into() + } else { + format!("\"{}\"", x).into() + }; + let l = tt::Literal { span: tt::TokenId::unspecified(), text }; quote!(#l ,) }); let arg_tts = arg_tts.into_iter().flat_map(|arg| arg.token_trees); |
