From 642ca5491aae038ad7584ba6895e251b3817f93f Mon Sep 17 00:00:00 2001 From: Will Crichton Date: Fri, 8 Apr 2022 15:00:24 -0700 Subject: [PATCH] Ensure host units don't depend on Docscrape units, fixes #10535 --- src/cargo/core/compiler/mod.rs | 2 +- src/cargo/core/compiler/unit_dependencies.rs | 4 +- src/cargo/core/workspace.rs | 10 ++++ tests/testsuite/doc.rs | 52 ++++++++++++++++++++ 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 5abd06a75bd..2474a9202bd 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -682,7 +682,7 @@ fn rustdoc(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult { rustdoc.arg("--scrape-examples-target-crate").arg(name); } } - } else if cx.bcx.scrape_units.len() > 0 && cx.bcx.ws.is_member(&unit.pkg) { + } else if cx.bcx.scrape_units.len() > 0 && cx.bcx.ws.unit_needs_doc_scrape(unit) { // We only pass scraped examples to packages in the workspace // since examples are only coming from reverse-dependencies of workspace packages diff --git a/src/cargo/core/compiler/unit_dependencies.rs b/src/cargo/core/compiler/unit_dependencies.rs index cf1b74a7367..4bd8aedf2b2 100644 --- a/src/cargo/core/compiler/unit_dependencies.rs +++ b/src/cargo/core/compiler/unit_dependencies.rs @@ -708,8 +708,8 @@ fn compute_deps_doc( } } - // Add all units being scraped for examples as a dependency of Doc units. - if state.ws.is_member(&unit.pkg) { + // Add all units being scraped for examples as a dependency of top-level Doc units. + if state.ws.unit_needs_doc_scrape(unit) { for scrape_unit in state.scrape_units.iter() { deps_of(scrape_unit, state, unit_for)?; ret.push(new_unit_dep( diff --git a/src/cargo/core/workspace.rs b/src/cargo/core/workspace.rs index 4c9a5936ff4..b24ab13046e 100644 --- a/src/cargo/core/workspace.rs +++ b/src/cargo/core/workspace.rs @@ -11,6 +11,7 @@ use log::debug; use toml_edit::easy as toml; use url::Url; +use crate::core::compiler::Unit; use crate::core::features::Features; use crate::core::registry::PackageRegistry; use crate::core::resolver::features::CliFeatures; @@ -1500,6 +1501,15 @@ impl<'cfg> Workspace<'cfg> { ms } + + /// Returns true if `unit` should depend on the output of Docscrape units. + pub fn unit_needs_doc_scrape(&self, unit: &Unit) -> bool { + // We do not add scraped units for Host units, as they're either build scripts + // (not documented) or proc macros (have no scrape-able exports). Additionally, + // naively passing a proc macro's unit_for to new_unit_dep will currently cause + // Cargo to panic, see issue #10545. + self.is_member(&unit.pkg) && !unit.target.for_host() + } } impl<'cfg> Packages<'cfg> { diff --git a/tests/testsuite/doc.rs b/tests/testsuite/doc.rs index dd6a3ec46ca..9e18cee1e10 100644 --- a/tests/testsuite/doc.rs +++ b/tests/testsuite/doc.rs @@ -2593,6 +2593,58 @@ fn scrape_examples_configure_profile() { assert!(doc_html.contains("More examples")); } +#[cargo_test] +fn scrape_examples_issue_10545() { + if !is_nightly() { + // -Z rustdoc-scrape-examples is unstable + return; + } + + let p = project() + .file( + "Cargo.toml", + r#" + [workspace] + resolver = "2" + members = ["a", "b"] + "#, + ) + .file( + "a/Cargo.toml", + r#" + [package] + name = "a" + version = "0.0.1" + authors = [] + edition = "2021" + + [features] + default = ["foo"] + foo = [] + "#, + ) + .file("a/src/lib.rs", "") + .file( + "b/Cargo.toml", + r#" + [package] + name = "b" + version = "0.0.1" + authors = [] + edition = "2021" + + [lib] + proc-macro = true + "#, + ) + .file("b/src/lib.rs", "") + .build(); + + p.cargo("doc -Zunstable-options -Z rustdoc-scrape-examples=all") + .masquerade_as_nightly_cargo() + .run(); +} + #[cargo_test] fn lib_before_bin() { // Checks that the library is documented before the binary.