about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2025-05-14 16:48:05 +0000
committerMatthew Jasper <mjjasper1@gmail.com>2025-05-27 15:57:41 +0000
commite5bfd02c5e8c9176be0bf279a8669d56abe66a5f (patch)
tree8e700db111f8e792d079578d0490aca50ff6465f
parent65bdb31a97af553c4fd932a171b74eaad76c1c53 (diff)
downloadrust-e5bfd02c5e8c9176be0bf279a8669d56abe66a5f.tar.gz
rust-e5bfd02c5e8c9176be0bf279a8669d56abe66a5f.zip
Avoid including text direction codepoints in lint messages
-rw-r--r--Cargo.lock1
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs8
-rw-r--r--src/tools/lint-docs/Cargo.toml1
-rw-r--r--src/tools/lint-docs/src/lib.rs11
4 files changed, 17 insertions, 4 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 177ff6594e2..7b117130683 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2170,6 +2170,7 @@ dependencies = [
 name = "lint-docs"
 version = "0.1.0"
 dependencies = [
+ "rustc-literal-escaper",
  "serde_json",
  "tempfile",
  "walkdir",
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 9b97e66e3f8..9c550a12ce1 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -7,8 +7,6 @@
 //! When removing a lint, make sure to also add a call to `register_removed` in
 //! compiler/rustc_lint/src/lib.rs.
 
-#![allow(text_direction_codepoint_in_literal)]
-
 use rustc_span::edition::Edition;
 
 use crate::{FutureIncompatibilityReason, declare_lint, declare_lint_pass};
@@ -3796,7 +3794,7 @@ declare_lint! {
     /// ```rust,compile_fail
     /// #![deny(text_direction_codepoint_in_comment)]
     /// fn main() {
-    ///     println!("{:?}"); // '‮');
+    #[doc = "    println!(\"{:?}\"); // '\u{202E}');"]
     /// }
     /// ```
     ///
@@ -3834,7 +3832,9 @@ declare_lint! {
     /// ```rust,compile_fail
     /// #![deny(text_direction_codepoint_in_literal)]
     /// fn main() {
-    ///     println!("{:?}", '‮');
+    // ` - convince tidy that backticks match
+    #[doc = "    println!(\"{:?}\", '\u{202E}');"]
+    // `
     /// }
     /// ```
     ///
diff --git a/src/tools/lint-docs/Cargo.toml b/src/tools/lint-docs/Cargo.toml
index 3578bda8276..f1ffda75ac0 100644
--- a/src/tools/lint-docs/Cargo.toml
+++ b/src/tools/lint-docs/Cargo.toml
@@ -7,6 +7,7 @@ description = "A script to extract the lint documentation for the rustc book."
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
+rustc-literal-escaper = "0.0.2"
 serde_json = "1.0.57"
 tempfile = "3.1.0"
 walkdir = "2.3.1"
diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs
index cacce01675f..6bb18c2bced 100644
--- a/src/tools/lint-docs/src/lib.rs
+++ b/src/tools/lint-docs/src/lib.rs
@@ -4,6 +4,7 @@ use std::fs;
 use std::path::{Path, PathBuf};
 use std::process::Command;
 
+use rustc_literal_escaper::{Mode, unescape_unicode};
 use walkdir::WalkDir;
 
 mod groups;
@@ -214,6 +215,16 @@ impl<'a> LintExtractor<'a> {
                         let line = line.trim();
                         if let Some(text) = line.strip_prefix("/// ") {
                             doc_lines.push(text.to_string());
+                        } else if let Some(text) = line.strip_prefix("#[doc = \"") {
+                            let escaped = text.strip_suffix("\"]").unwrap();
+                            let mut buf = String::new();
+                            unescape_unicode(escaped, Mode::Str, &mut |_, c| match c {
+                                Ok(c) => buf.push(c),
+                                Err(err) => {
+                                    assert!(!err.is_fatal(), "failed to unescape string literal")
+                                }
+                            });
+                            doc_lines.push(buf);
                         } else if line == "///" {
                             doc_lines.push("".to_string());
                         } else if line.starts_with("// ") {