about summary refs log tree commit diff
diff options
context:
space:
mode:
authorStuart Cook <Zalathar@users.noreply.github.com>2025-07-29 20:19:52 +1000
committerGitHub <noreply@github.com>2025-07-29 20:19:52 +1000
commit03bb80c25453a58cec0b918c57402fe6e6372ea6 (patch)
tree440c191b1d27c76d02a9a70ce354212b09f95de8
parent0abc0c4201b6c6d892c3e280753c8ba07c1d8fd2 (diff)
parent327ee15959949c808da2498f7337a5fa5e415c08 (diff)
downloadrust-03bb80c25453a58cec0b918c57402fe6e6372ea6.tar.gz
rust-03bb80c25453a58cec0b918c57402fe6e6372ea6.zip
Rollup merge of #144600 - Noratrieb:rustdoc-dep-info-paths, r=GuillaumeGomez
Ensure external paths passed via flags end up in rustdoc depinfo

rustdoc has many flags to pass external HTML/Markdown/CSS files that end up in the build. These need to be recorded in depinfo so that Cargo will rebuild the crate if they change.
-rw-r--r--src/librustdoc/config.rs20
-rw-r--r--src/librustdoc/externalfiles.rs23
-rw-r--r--src/librustdoc/lib.rs8
-rw-r--r--src/librustdoc/scrape_examples.rs2
-rw-r--r--tests/run-make/rustdoc-dep-info/after.md1
-rw-r--r--tests/run-make/rustdoc-dep-info/before.html0
-rw-r--r--tests/run-make/rustdoc-dep-info/extend.css0
-rw-r--r--tests/run-make/rustdoc-dep-info/rmake.rs15
-rw-r--r--tests/run-make/rustdoc-dep-info/theme.css1
9 files changed, 53 insertions, 17 deletions
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 57456e906de..fed4296fa22 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -380,7 +380,7 @@ impl Options {
         early_dcx: &mut EarlyDiagCtxt,
         matches: &getopts::Matches,
         args: Vec<String>,
-    ) -> Option<(InputMode, Options, RenderOptions)> {
+    ) -> Option<(InputMode, Options, RenderOptions, Vec<PathBuf>)> {
         // Check for unstable options.
         nightly_options::check_nightly_options(early_dcx, matches, &opts());
 
@@ -643,10 +643,13 @@ impl Options {
 
         let extension_css = matches.opt_str("e").map(|s| PathBuf::from(&s));
 
-        if let Some(ref p) = extension_css
-            && !p.is_file()
-        {
-            dcx.fatal("option --extend-css argument must be a file");
+        let mut loaded_paths = Vec::new();
+
+        if let Some(ref p) = extension_css {
+            loaded_paths.push(p.clone());
+            if !p.is_file() {
+                dcx.fatal("option --extend-css argument must be a file");
+            }
         }
 
         let mut themes = Vec::new();
@@ -690,6 +693,7 @@ impl Options {
                     ))
                     .emit();
                 }
+                loaded_paths.push(theme_file.clone());
                 themes.push(StylePath { path: theme_file });
             }
         }
@@ -708,6 +712,7 @@ impl Options {
             &mut id_map,
             edition,
             &None,
+            &mut loaded_paths,
         ) else {
             dcx.fatal("`ExternalHtml::load` failed");
         };
@@ -799,7 +804,8 @@ impl Options {
 
         let scrape_examples_options = ScrapeExamplesOptions::new(matches, dcx);
         let with_examples = matches.opt_strs("with-examples");
-        let call_locations = crate::scrape_examples::load_call_locations(with_examples, dcx);
+        let call_locations =
+            crate::scrape_examples::load_call_locations(with_examples, dcx, &mut loaded_paths);
         let doctest_build_args = matches.opt_strs("doctest-build-arg");
 
         let unstable_features =
@@ -885,7 +891,7 @@ impl Options {
             parts_out_dir,
             disable_minification,
         };
-        Some((input, options, render_options))
+        Some((input, options, render_options, loaded_paths))
     }
 }
 
diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs
index ea2aa963edd..42ade5b9004 100644
--- a/src/librustdoc/externalfiles.rs
+++ b/src/librustdoc/externalfiles.rs
@@ -1,4 +1,4 @@
-use std::path::Path;
+use std::path::{Path, PathBuf};
 use std::{fs, str};
 
 use rustc_errors::DiagCtxtHandle;
@@ -32,12 +32,13 @@ impl ExternalHtml {
         id_map: &mut IdMap,
         edition: Edition,
         playground: &Option<Playground>,
+        loaded_paths: &mut Vec<PathBuf>,
     ) -> Option<ExternalHtml> {
         let codes = ErrorCodes::from(nightly_build);
-        let ih = load_external_files(in_header, dcx)?;
+        let ih = load_external_files(in_header, dcx, loaded_paths)?;
         let bc = {
-            let mut bc = load_external_files(before_content, dcx)?;
-            let m_bc = load_external_files(md_before_content, dcx)?;
+            let mut bc = load_external_files(before_content, dcx, loaded_paths)?;
+            let m_bc = load_external_files(md_before_content, dcx, loaded_paths)?;
             Markdown {
                 content: &m_bc,
                 links: &[],
@@ -52,8 +53,8 @@ impl ExternalHtml {
             bc
         };
         let ac = {
-            let mut ac = load_external_files(after_content, dcx)?;
-            let m_ac = load_external_files(md_after_content, dcx)?;
+            let mut ac = load_external_files(after_content, dcx, loaded_paths)?;
+            let m_ac = load_external_files(md_after_content, dcx, loaded_paths)?;
             Markdown {
                 content: &m_ac,
                 links: &[],
@@ -79,8 +80,10 @@ pub(crate) enum LoadStringError {
 pub(crate) fn load_string<P: AsRef<Path>>(
     file_path: P,
     dcx: DiagCtxtHandle<'_>,
+    loaded_paths: &mut Vec<PathBuf>,
 ) -> Result<String, LoadStringError> {
     let file_path = file_path.as_ref();
+    loaded_paths.push(file_path.to_owned());
     let contents = match fs::read(file_path) {
         Ok(bytes) => bytes,
         Err(e) => {
@@ -101,10 +104,14 @@ pub(crate) fn load_string<P: AsRef<Path>>(
     }
 }
 
-fn load_external_files(names: &[String], dcx: DiagCtxtHandle<'_>) -> Option<String> {
+fn load_external_files(
+    names: &[String],
+    dcx: DiagCtxtHandle<'_>,
+    loaded_paths: &mut Vec<PathBuf>,
+) -> Option<String> {
     let mut out = String::new();
     for name in names {
-        let Ok(s) = load_string(name, dcx) else { return None };
+        let Ok(s) = load_string(name, dcx, loaded_paths) else { return None };
         out.push_str(&s);
         out.push('\n');
     }
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index a3cdc4f687f..7431ff8e1ad 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -799,7 +799,7 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
 
     // Note that we discard any distinction between different non-zero exit
     // codes from `from_matches` here.
-    let (input, options, render_options) =
+    let (input, options, render_options, loaded_paths) =
         match config::Options::from_matches(early_dcx, &matches, args) {
             Some(opts) => opts,
             None => return,
@@ -870,6 +870,12 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
     interface::run_compiler(config, |compiler| {
         let sess = &compiler.sess;
 
+        // Register the loaded external files in the source map so they show up in depinfo.
+        // We can't load them via the source map because it gets created after we process the options.
+        for external_path in &loaded_paths {
+            let _ = sess.source_map().load_file(external_path);
+        }
+
         if sess.opts.describe_lints {
             rustc_driver::describe_lints(sess, registered_lints);
             return;
diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs
index fceacb69fb5..4d29c74e1eb 100644
--- a/src/librustdoc/scrape_examples.rs
+++ b/src/librustdoc/scrape_examples.rs
@@ -333,9 +333,11 @@ pub(crate) fn run(
 pub(crate) fn load_call_locations(
     with_examples: Vec<String>,
     dcx: DiagCtxtHandle<'_>,
+    loaded_paths: &mut Vec<PathBuf>,
 ) -> AllCallLocations {
     let mut all_calls: AllCallLocations = FxIndexMap::default();
     for path in with_examples {
+        loaded_paths.push(path.clone().into());
         let bytes = match fs::read(&path) {
             Ok(bytes) => bytes,
             Err(e) => dcx.fatal(format!("failed to load examples: {e}")),
diff --git a/tests/run-make/rustdoc-dep-info/after.md b/tests/run-make/rustdoc-dep-info/after.md
new file mode 100644
index 00000000000..10d4b4c4116
--- /dev/null
+++ b/tests/run-make/rustdoc-dep-info/after.md
@@ -0,0 +1 @@
+meow! :3
diff --git a/tests/run-make/rustdoc-dep-info/before.html b/tests/run-make/rustdoc-dep-info/before.html
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/tests/run-make/rustdoc-dep-info/before.html
diff --git a/tests/run-make/rustdoc-dep-info/extend.css b/tests/run-make/rustdoc-dep-info/extend.css
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/tests/run-make/rustdoc-dep-info/extend.css
diff --git a/tests/run-make/rustdoc-dep-info/rmake.rs b/tests/run-make/rustdoc-dep-info/rmake.rs
index db7a00a5ce2..625f81fd428 100644
--- a/tests/run-make/rustdoc-dep-info/rmake.rs
+++ b/tests/run-make/rustdoc-dep-info/rmake.rs
@@ -9,13 +9,26 @@ use run_make_support::{path, rfs, rustdoc};
 fn main() {
     // We're only emitting dep info, so we shouldn't be running static analysis to
     // figure out that this program is erroneous.
-    rustdoc().input("lib.rs").arg("-Zunstable-options").emit("dep-info").run();
+    // Ensure that all kinds of input reading flags end up in dep-info.
+    rustdoc()
+        .input("lib.rs")
+        .arg("-Zunstable-options")
+        .arg("--html-before-content=before.html")
+        .arg("--markdown-after-content=after.md")
+        .arg("--extend-css=extend.css")
+        .arg("--theme=theme.css")
+        .emit("dep-info")
+        .run();
 
     let content = rfs::read_to_string("foo.d");
     assert_contains(&content, "lib.rs:");
     assert_contains(&content, "foo.rs:");
     assert_contains(&content, "bar.rs:");
     assert_contains(&content, "doc.md:");
+    assert_contains(&content, "after.md:");
+    assert_contains(&content, "before.html:");
+    assert_contains(&content, "extend.css:");
+    assert_contains(&content, "theme.css:");
 
     // Now we check that we can provide a file name to the `dep-info` argument.
     rustdoc().input("lib.rs").arg("-Zunstable-options").emit("dep-info=bla.d").run();
diff --git a/tests/run-make/rustdoc-dep-info/theme.css b/tests/run-make/rustdoc-dep-info/theme.css
new file mode 100644
index 00000000000..459daffa9a1
--- /dev/null
+++ b/tests/run-make/rustdoc-dep-info/theme.css
@@ -0,0 +1 @@
+/* This is not a valid theme but that doesn't really matter */