fix(mbe): desugar doc correctly for mbe

Fixes #16110.

The way rust desugars doc comments when expanding macros
is rendering it as raw strings delimited with hashes.
Rust-analyzer wasn't aware of this, so the desugared doc
comments wouldn't match correctly when on the LHS of macro
declarations.

This PR fixes this by porting the code used by rustc: 4cfdbd328b/compiler/rustc_ast/src/tokenstream.rs (L6837)
This commit is contained in:
Luiz Carvalho 2023-12-19 00:32:55 -03:00
parent f6635211ce
commit 117a28a065
No known key found for this signature in database
2 changed files with 22 additions and 7 deletions

View File

@ -1218,8 +1218,10 @@ m! {
macro_rules! m { macro_rules! m {
($(#[$m:meta])+) => ( $(#[$m])+ fn bar() {} ) ($(#[$m:meta])+) => ( $(#[$m])+ fn bar() {} )
} }
#[doc = " Single Line Doc 1"] #[doc = r" Single Line Doc 1"]
#[doc = "\n MultiLines Doc\n "] fn bar() {} #[doc = "
MultiLines Doc
"] fn bar() {}
"##]], "##]],
); );
} }
@ -1260,8 +1262,10 @@ m! {
macro_rules! m { macro_rules! m {
($(#[$ m:meta])+) => ( $(#[$m])+ fn bar() {} ) ($(#[$ m:meta])+) => ( $(#[$m])+ fn bar() {} )
} }
#[doc = " 錦瑟無端五十弦,一弦一柱思華年。"] #[doc = r" 錦瑟無端五十弦,一弦一柱思華年。"]
#[doc = "\n 莊生曉夢迷蝴蝶,望帝春心託杜鵑。\n "] fn bar() {} #[doc = r"
"] fn bar() {}
"##]], "##]],
); );
} }
@ -1281,7 +1285,7 @@ m! {
macro_rules! m { macro_rules! m {
($(#[$m:meta])+) => ( $(#[$m])+ fn bar() {} ) ($(#[$m:meta])+) => ( $(#[$m])+ fn bar() {} )
} }
#[doc = " \\ \" \'"] fn bar() {} #[doc = r#" \ " '"#] fn bar() {}
"##]], "##]],
); );
} }

View File

@ -406,9 +406,20 @@ fn doc_comment_text(comment: &ast::Comment) -> SmolStr {
text = &text[0..text.len() - 2]; text = &text[0..text.len() - 2];
} }
// Quote the string let mut num_of_hashes = 0;
let mut count = 0;
for ch in text.chars() {
count = match ch {
'"' => 1,
'#' if count > 0 => count + 1,
_ => 0,
};
num_of_hashes = num_of_hashes.max(count);
}
// Quote raw string with delimiters
// Note that `tt::Literal` expect an escaped string // Note that `tt::Literal` expect an escaped string
let text = format!("\"{}\"", text.escape_debug()); let text = format!("r{delim}\"{text}\"{delim}", delim = "#".repeat(num_of_hashes));
text.into() text.into()
} }