From f92be7eaabe27387a2d860c3842443bf32e99c73 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sun, 18 Apr 2021 03:16:38 +0300 Subject: Escape characters in doc comments in macros correctly Previously they were escaped twice, both by `.escape_default()` and the debug view of strings (`{:?}`). This leads to things like newlines or tabs in documentation comments being `\\n`, but we unescape literals only once, ending up with `\n`. This was hard to spot because CMark unescaped them (at least for `'` and `"`), but it did not do so in code blocks. This also was the root cause of #7781. This issue was solved by using `.escape_debug()` instead of `.escape_default()`, but the real issue remained. We can bring the `.escape_default()` back by now, however I didn't do it because it is probably slower than `.escape_debug()` (more work to do), and also in order to change the code the least. --- crates/mbe/src/syntax_bridge.rs | 2 +- crates/mbe/src/tests/expand.rs | 24 ++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) (limited to 'crates/mbe/src') diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs index 9d433b3b0..cfab99da8 100644 --- a/crates/mbe/src/syntax_bridge.rs +++ b/crates/mbe/src/syntax_bridge.rs @@ -213,7 +213,7 @@ fn doc_comment_text(comment: &ast::Comment) -> SmolStr { // Quote the string // Note that `tt::Literal` expect an escaped string - let text = format!("{:?}", text.escape_debug().to_string()); + let text = format!("\"{}\"", text.escape_debug()); text.into() } diff --git a/crates/mbe/src/tests/expand.rs b/crates/mbe/src/tests/expand.rs index 8951f3813..84f19d3e2 100644 --- a/crates/mbe/src/tests/expand.rs +++ b/crates/mbe/src/tests/expand.rs @@ -921,7 +921,7 @@ fn test_meta_doc_comments() { MultiLines Doc */ }"#, - "# [doc = \" Single Line Doc 1\"] # [doc = \"\\\\n MultiLines Doc\\\\n \"] fn bar () {}", + "# [doc = \" Single Line Doc 1\"] # [doc = \"\\n MultiLines Doc\\n \"] fn bar () {}", ); } @@ -944,7 +944,27 @@ fn test_meta_doc_comments_non_latin() { 莊生曉夢迷蝴蝶,望帝春心託杜鵑。 */ }"#, - "# [doc = \" 錦瑟無端五十弦,一弦一柱思華年。\"] # [doc = \"\\\\n 莊生曉夢迷蝴蝶,望帝春心託杜鵑。\\\\n \"] fn bar () {}", + "# [doc = \" 錦瑟無端五十弦,一弦一柱思華年。\"] # [doc = \"\\n 莊生曉夢迷蝴蝶,望帝春心託杜鵑。\\n \"] fn bar () {}", + ); +} + +#[test] +fn test_meta_doc_comments_escaped_characters() { + parse_macro( + r#" + macro_rules! foo { + ($(#[$ i:meta])+) => ( + $(#[$ i])+ + fn bar() {} + ) + } +"#, + ) + .assert_expand_items( + r#"foo! { + /// \ " ' + }"#, + r#"# [doc = " \\ \" \'"] fn bar () {}"#, ); } -- cgit v1.2.3