From 6c287e150433e848c97b89c7211a3464a5675634 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sun, 18 Apr 2021 05:09:20 +0300 Subject: Accept `E` notation in doctests ```compile_fail,E0000 ``` The code was stolen from rustdoc at https://github.com/rust-lang/rust/blob/392ba2ba1a7d6c542d2459fb8133bebf62a4a423/src/librustdoc/html/markdown.rs#L866-L867 --- crates/ide/src/syntax_highlighting/inject.rs | 10 ++++++++-- crates/rust-analyzer/src/markdown.rs | 18 +++++++++++++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs index 04fafd244..855c7fba8 100644 --- a/crates/ide/src/syntax_highlighting/inject.rs +++ b/crates/ide/src/syntax_highlighting/inject.rs @@ -90,6 +90,13 @@ const RUSTDOC_FENCE_TOKENS: &[&'static str] = &[ "edition2021", ]; +fn is_rustdoc_fence_token(token: &str) -> bool { + if RUSTDOC_FENCE_TOKENS.contains(&token) { + return true; + } + token.starts_with('E') && token.len() == 5 && token[1..].parse::().is_ok() +} + /// Injection of syntax highlighting of doctests. pub(super) fn doc_comment( hl: &mut Highlights, @@ -174,8 +181,7 @@ pub(super) fn doc_comment( is_codeblock = !is_codeblock; // Check whether code is rust by inspecting fence guards let guards = &line[idx + RUSTDOC_FENCE.len()..]; - let is_rust = - guards.split(',').all(|sub| RUSTDOC_FENCE_TOKENS.contains(&sub.trim())); + let is_rust = guards.split(',').all(|sub| is_rustdoc_fence_token(sub.trim())); is_doctest = is_codeblock && is_rust; continue; } diff --git a/crates/rust-analyzer/src/markdown.rs b/crates/rust-analyzer/src/markdown.rs index 865eaae9b..a51ff89e4 100644 --- a/crates/rust-analyzer/src/markdown.rs +++ b/crates/rust-analyzer/src/markdown.rs @@ -27,9 +27,8 @@ pub(crate) fn format_docs(src: &str) -> String { in_code_block ^= true; if in_code_block { - is_rust = header - .split(',') - .all(|sub| RUSTDOC_CODE_BLOCK_ATTRIBUTES_RUST_SPECIFIC.contains(&sub.trim())); + is_rust = + header.split(',').all(|sub| is_rust_specific_code_block_attribute(sub.trim())); if is_rust { line = "```rust"; @@ -42,6 +41,13 @@ pub(crate) fn format_docs(src: &str) -> String { processed_lines.join("\n") } +fn is_rust_specific_code_block_attribute(attr: &str) -> bool { + if RUSTDOC_CODE_BLOCK_ATTRIBUTES_RUST_SPECIFIC.contains(&attr) { + return true; + } + attr.starts_with('E') && attr.len() == 5 && attr[1..].parse::().is_ok() +} + fn code_line_ignored_by_rustdoc(line: &str) -> bool { let trimmed = line.trim(); trimmed == "#" || trimmed.starts_with("# ") || trimmed.starts_with("#\t") @@ -81,6 +87,12 @@ mod tests { assert_eq!(format_docs(comment), "```rust\nlet z = 55;\n```"); } + #[test] + fn test_format_docs_handles_error_codes() { + let comment = "```compile_fail,E0641\nlet b = 0 as *const _;\n```"; + assert_eq!(format_docs(comment), "```rust\nlet b = 0 as *const _;\n```"); + } + #[test] fn test_format_docs_skips_comments_in_rust_block() { let comment = -- cgit v1.2.3