about summary refs log tree commit diff
path: root/src/tools
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-03-23 21:16:57 +0000
committerbors <bors@rust-lang.org>2023-03-23 21:16:57 +0000
commit1459b3128e288a85fcc4dd1fee7ada2cdcf28794 (patch)
treef31be534855b77ac6d4ac49aeb9374499be2fe0e /src/tools
parente2163008763c326ec4003e07b8e6eef0c98f6204 (diff)
parent3961ef5bc84f8f6057e34bf61b92561bef5c8e64 (diff)
downloadrust-1459b3128e288a85fcc4dd1fee7ada2cdcf28794.tar.gz
rust-1459b3128e288a85fcc4dd1fee7ada2cdcf28794.zip
Auto merge of #109538 - matthiaskrgr:rollup-ct58npj, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #106964 (Clarify `Error::last_os_error` can be weird)
 - #107718 (Add `-Z time-passes-format` to allow specifying a JSON output for `-Z time-passes`)
 - #107880 (Lint ambiguous glob re-exports)
 - #108549 (Remove issue number for `link_cfg`)
 - #108588 (Fix the ffi_unwind_calls lint documentation)
 - #109231 (Add `try_canonicalize` to `rustc_fs_util` and use it over `fs::canonicalize`)
 - #109472 (Add parentheses properly for method calls)
 - #109487 (Move useless_anynous_reexport lint into unused_imports)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/lint-docs/src/lib.rs95
1 files changed, 62 insertions, 33 deletions
diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs
index 3842a649c6f..034c6aa0708 100644
--- a/src/tools/lint-docs/src/lib.rs
+++ b/src/tools/lint-docs/src/lib.rs
@@ -45,6 +45,36 @@ impl Lint {
     fn check_style(&self) -> Result<(), Box<dyn Error>> {
         for &expected in &["### Example", "### Explanation", "{{produces}}"] {
             if expected == "{{produces}}" && self.is_ignored() {
+                if self.doc_contains("{{produces}}") {
+                    return Err(format!(
+                        "the lint example has `ignore`, but also contains the {{{{produces}}}} marker\n\
+                        \n\
+                        The documentation generator cannot generate the example output when the \
+                        example is ignored.\n\
+                        Manually include the sample output below the example. For example:\n\
+                        \n\
+                        /// ```rust,ignore (needs command line option)\n\
+                        /// #[cfg(widnows)]\n\
+                        /// fn foo() {{}}\n\
+                        /// ```\n\
+                        ///\n\
+                        /// This will produce:\n\
+                        /// \n\
+                        /// ```text\n\
+                        /// warning: unknown condition name used\n\
+                        ///  --> lint_example.rs:1:7\n\
+                        ///   |\n\
+                        /// 1 | #[cfg(widnows)]\n\
+                        ///   |       ^^^^^^^\n\
+                        ///   |\n\
+                        ///   = note: `#[warn(unexpected_cfgs)]` on by default\n\
+                        /// ```\n\
+                        \n\
+                        Replacing the output with the text of the example you \
+                        compiled manually yourself.\n\
+                        "
+                    ).into());
+                }
                 continue;
             }
             if !self.doc_contains(expected) {
@@ -317,10 +347,10 @@ impl<'a> LintExtractor<'a> {
                             ..,
                             &format!(
                                 "This will produce:\n\
-                            \n\
-                            ```text\n\
-                            {}\
-                            ```",
+                                \n\
+                                ```text\n\
+                                {}\
+                                ```",
                                 output
                             ),
                         );
@@ -392,37 +422,36 @@ impl<'a> LintExtractor<'a> {
             .filter(|line| line.starts_with('{'))
             .map(serde_json::from_str)
             .collect::<Result<Vec<serde_json::Value>, _>>()?;
-        match msgs
+        // First try to find the messages with the `code` field set to our lint.
+        let matches: Vec<_> = msgs
             .iter()
-            .find(|msg| matches!(&msg["code"]["code"], serde_json::Value::String(s) if s==name))
-        {
-            Some(msg) => {
-                let rendered = msg["rendered"].as_str().expect("rendered field should exist");
-                Ok(rendered.to_string())
-            }
-            None => {
-                match msgs.iter().find(
-                    |msg| matches!(&msg["rendered"], serde_json::Value::String(s) if s.contains(name)),
-                ) {
-                    Some(msg) => {
-                        let rendered = msg["rendered"].as_str().expect("rendered field should exist");
-                        Ok(rendered.to_string())
-                    }
-                    None => {
-                        let rendered: Vec<&str> =
-                            msgs.iter().filter_map(|msg| msg["rendered"].as_str()).collect();
-                        let non_json: Vec<&str> =
-                            stderr.lines().filter(|line| !line.starts_with('{')).collect();
-                        Err(format!(
-                            "did not find lint `{}` in output of example, got:\n{}\n{}",
-                            name,
-                            non_json.join("\n"),
-                            rendered.join("\n")
-                        )
-                        .into())
-                    }
-                }
+            .filter(|msg| matches!(&msg["code"]["code"], serde_json::Value::String(s) if s==name))
+            .map(|msg| msg["rendered"].as_str().expect("rendered field should exist").to_string())
+            .collect();
+        if matches.is_empty() {
+            // Some lints override their code to something else (E0566).
+            // Try to find something that looks like it could be our lint.
+            let matches: Vec<_> = msgs.iter().filter(|msg|
+                matches!(&msg["rendered"], serde_json::Value::String(s) if s.contains(name)))
+                .map(|msg| msg["rendered"].as_str().expect("rendered field should exist").to_string())
+                .collect();
+            if matches.is_empty() {
+                let rendered: Vec<&str> =
+                    msgs.iter().filter_map(|msg| msg["rendered"].as_str()).collect();
+                let non_json: Vec<&str> =
+                    stderr.lines().filter(|line| !line.starts_with('{')).collect();
+                Err(format!(
+                    "did not find lint `{}` in output of example, got:\n{}\n{}",
+                    name,
+                    non_json.join("\n"),
+                    rendered.join("\n")
+                )
+                .into())
+            } else {
+                Ok(matches.join("\n"))
             }
+        } else {
+            Ok(matches.join("\n"))
         }
     }