Skip to content

Commit cd59ae5

Browse files
committed
Change rustdoc-scrape-examples to be a target-level configuration
1 parent de4bd68 commit cd59ae5

File tree

8 files changed

+113
-80
lines changed

8 files changed

+113
-80
lines changed

src/cargo/core/compiler/job_queue.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,8 +431,9 @@ impl<'cfg> JobQueue<'cfg> {
431431
.filter(|dep| {
432432
// Binaries aren't actually needed to *compile* tests, just to run
433433
// them, so we don't include this dependency edge in the job graph.
434+
// But we shouldn't filter out dependencies being scraped for Rustdoc.
434435
(!dep.unit.target.is_test() && !dep.unit.target.is_bin())
435-
|| dep.unit.artifact.is_true()
436+
|| dep.unit.artifact.is_true() || dep.unit.mode.is_doc_scrape()
436437
})
437438
.map(|dep| {
438439
// Handle the case here where our `unit -> dep` dependency may

src/cargo/core/compiler/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,10 @@ fn rustdoc(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Work> {
666666
if unit.mode.is_doc_scrape() {
667667
debug_assert!(cx.bcx.scrape_units.contains(unit));
668668

669+
if unit.target.is_test() {
670+
rustdoc.arg("--test");
671+
}
672+
669673
rustdoc.arg("-Zunstable-options");
670674

671675
rustdoc

src/cargo/core/features.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -661,9 +661,6 @@ unstable_cli_options!(
661661
separate_nightlies: bool = (HIDDEN),
662662
terminal_width: Option<Option<usize>> = ("Provide a terminal width to rustc for error truncation"),
663663
unstable_options: bool = ("Allow the usage of unstable options"),
664-
// TODO(wcrichto): move scrape example configuration into Cargo.toml before stabilization
665-
// See: https://github.com/rust-lang/cargo/pull/9525#discussion_r728470927
666-
rustdoc_scrape_examples: Option<String> = ("Allow rustdoc to scrape examples from reverse-dependencies for documentation"),
667664
skip_rustdoc_fingerprint: bool = (HIDDEN),
668665
);
669666

@@ -887,15 +884,6 @@ impl CliUnstable {
887884
"namespaced-features" => stabilized_warn(k, "1.60", STABILISED_NAMESPACED_FEATURES),
888885
"weak-dep-features" => stabilized_warn(k, "1.60", STABILIZED_WEAK_DEP_FEATURES),
889886
"credential-process" => self.credential_process = parse_empty(k, v)?,
890-
"rustdoc-scrape-examples" => {
891-
if let Some(s) = v {
892-
self.rustdoc_scrape_examples = Some(s.to_string())
893-
} else {
894-
bail!(
895-
r#"-Z rustdoc-scrape-examples must take "all" or "examples" as an argument"#
896-
)
897-
}
898-
}
899887
"skip-rustdoc-fingerprint" => self.skip_rustdoc_fingerprint = parse_empty(k, v)?,
900888
"compile-progress" => stabilized_warn(k, "1.30", STABILIZED_COMPILE_PROGRESS),
901889
"offline" => stabilized_err(k, "1.36", STABILIZED_OFFLINE)?,

src/cargo/core/manifest.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ struct TargetInner {
220220
for_host: bool,
221221
proc_macro: bool,
222222
edition: Edition,
223+
doc_scrape_examples: Option<bool>,
223224
}
224225

225226
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
@@ -373,6 +374,7 @@ compact_debug! {
373374
for_host
374375
proc_macro
375376
edition
377+
doc_scrape_examples
376378
)]
377379
}
378380
}
@@ -648,6 +650,7 @@ impl Target {
648650
harness: true,
649651
for_host: false,
650652
proc_macro: false,
653+
doc_scrape_examples: None,
651654
edition,
652655
tested: true,
653656
benched: true,
@@ -804,6 +807,14 @@ impl Target {
804807
pub fn edition(&self) -> Edition {
805808
self.inner.edition
806809
}
810+
pub fn doc_scrape_examples(&self) -> bool {
811+
self.inner.doc_scrape_examples.unwrap_or_else(|| {
812+
matches!(
813+
self.kind(),
814+
TargetKind::Lib(..) | TargetKind::ExampleBin | TargetKind::ExampleLib(..)
815+
)
816+
})
817+
}
807818
pub fn benched(&self) -> bool {
808819
self.inner.benched
809820
}
@@ -918,6 +929,10 @@ impl Target {
918929
Arc::make_mut(&mut self.inner).edition = edition;
919930
self
920931
}
932+
pub fn set_doc_scrape_examples(&mut self, doc_scrape_examples: bool) -> &mut Target {
933+
Arc::make_mut(&mut self.inner).doc_scrape_examples = Some(doc_scrape_examples);
934+
self
935+
}
921936
pub fn set_harness(&mut self, harness: bool) -> &mut Target {
922937
Arc::make_mut(&mut self.inner).harness = harness;
923938
self

src/cargo/ops/cargo_compile.rs

Lines changed: 24 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use crate::util::interning::InternedString;
4545
use crate::util::restricted_names::is_glob_pattern;
4646
use crate::util::{closest_msg, profile, CargoResult, StableHasher};
4747

48-
use anyhow::{bail, Context as _};
48+
use anyhow::Context as _;
4949

5050
/// Contains information about how a package should be compiled.
5151
///
@@ -370,8 +370,7 @@ pub fn create_bcx<'a, 'cfg>(
370370
let target_data = RustcTargetData::new(ws, &build_config.requested_kinds)?;
371371

372372
let all_packages = &Packages::All;
373-
let rustdoc_scrape_examples = &config.cli_unstable().rustdoc_scrape_examples;
374-
let need_reverse_dependencies = rustdoc_scrape_examples.is_some();
373+
let need_reverse_dependencies = matches!(build_config.mode, CompileMode::Doc { .. });
375374
let full_specs = if need_reverse_dependencies {
376375
all_packages
377376
} else {
@@ -511,47 +510,26 @@ pub fn create_bcx<'a, 'cfg>(
511510
override_rustc_crate_types(&mut units, args, interner)?;
512511
}
513512

514-
let mut scrape_units = match rustdoc_scrape_examples {
515-
Some(arg) => {
516-
let filter = match arg.as_str() {
517-
"all" => CompileFilter::new_all_targets(),
518-
"examples" => CompileFilter::new(
519-
LibRule::False,
520-
FilterRule::none(),
521-
FilterRule::none(),
522-
FilterRule::All,
523-
FilterRule::none(),
524-
),
525-
_ => {
526-
bail!(
527-
r#"-Z rustdoc-scrape-examples must take "all" or "examples" as an argument"#
528-
)
529-
}
530-
};
531-
let to_build_ids = resolve.specs_to_ids(&resolve_specs)?;
532-
let to_builds = pkg_set.get_many(to_build_ids)?;
533-
let mode = CompileMode::Docscrape;
534-
535-
generate_targets(
536-
ws,
537-
&to_builds,
538-
&filter,
539-
&build_config.requested_kinds,
540-
explicit_host_kind,
541-
mode,
542-
&resolve,
543-
&workspace_resolve,
544-
&resolved_features,
545-
&pkg_set,
546-
&profiles,
547-
interner,
548-
)?
549-
.into_iter()
550-
// Proc macros should not be scraped for functions, since they only export macros
551-
.filter(|unit| !unit.target.proc_macro())
552-
.collect::<Vec<_>>()
553-
}
554-
None => Vec::new(),
513+
let mut scrape_units = {
514+
let to_build_ids = resolve.specs_to_ids(&resolve_specs)?;
515+
let to_builds = pkg_set.get_many(to_build_ids)?;
516+
517+
generate_targets(
518+
ws,
519+
&to_builds,
520+
&CompileFilter::Default {
521+
required_features_filterable: false,
522+
},
523+
&build_config.requested_kinds,
524+
explicit_host_kind,
525+
CompileMode::Docscrape,
526+
&resolve,
527+
&workspace_resolve,
528+
&resolved_features,
529+
&pkg_set,
530+
&profiles,
531+
interner,
532+
)?
555533
};
556534

557535
let std_roots = if let Some(crates) = &config.cli_unstable().build_std {
@@ -1468,7 +1446,8 @@ fn filter_default_targets(targets: &[Target], mode: CompileMode) -> Vec<&Target>
14681446
})
14691447
.collect()
14701448
}
1471-
CompileMode::Doctest | CompileMode::Docscrape | CompileMode::RunCustomBuild => {
1449+
CompileMode::Docscrape => targets.iter().filter(|t| t.doc_scrape_examples()).collect(),
1450+
CompileMode::Doctest | CompileMode::RunCustomBuild => {
14721451
panic!("Invalid mode {:?}", mode)
14731452
}
14741453
}

src/cargo/util/toml/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2682,6 +2682,8 @@ struct TomlTarget {
26822682
bench: Option<bool>,
26832683
doc: Option<bool>,
26842684
plugin: Option<bool>,
2685+
#[serde(rename = "doc-scrape-examples")]
2686+
doc_scrape_examples: Option<bool>,
26852687
#[serde(rename = "proc-macro")]
26862688
proc_macro_raw: Option<bool>,
26872689
#[serde(rename = "proc_macro")]

src/cargo/util/toml/targets.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,10 @@ fn configure(toml: &TomlTarget, target: &mut Target) -> CargoResult<()> {
808808
.set_benched(toml.bench.unwrap_or_else(|| t2.benched()))
809809
.set_harness(toml.harness.unwrap_or_else(|| t2.harness()))
810810
.set_proc_macro(toml.proc_macro().unwrap_or_else(|| t2.proc_macro()))
811+
.set_doc_scrape_examples(
812+
toml.doc_scrape_examples
813+
.unwrap_or_else(|| t2.doc_scrape_examples()),
814+
)
811815
.set_for_host(match (toml.plugin, toml.proc_macro()) {
812816
(None, None) => t2.for_host(),
813817
(Some(true), _) | (_, Some(true)) => true,

tests/testsuite/doc.rs

Lines changed: 62 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2378,7 +2378,7 @@ fn scrape_examples_basic() {
23782378
.file("src/lib.rs", "pub fn foo() {}\npub fn bar() { foo(); }")
23792379
.build();
23802380

2381-
p.cargo("doc -Zunstable-options -Z rustdoc-scrape-examples=all")
2381+
p.cargo("doc")
23822382
.masquerade_as_nightly_cargo()
23832383
.with_stderr(
23842384
"\
@@ -2439,9 +2439,7 @@ fn scrape_examples_avoid_build_script_cycle() {
24392439
.file("bar/build.rs", "fn main(){}")
24402440
.build();
24412441

2442-
p.cargo("doc --all -Zunstable-options -Z rustdoc-scrape-examples=all")
2443-
.masquerade_as_nightly_cargo()
2444-
.run();
2442+
p.cargo("doc --all").masquerade_as_nightly_cargo().run();
24452443
}
24462444

24472445
#[cargo_test]
@@ -2501,9 +2499,34 @@ fn scrape_examples_complex_reverse_dependencies() {
25012499
.file("b/src/lib.rs", "")
25022500
.build();
25032501

2504-
p.cargo("doc -Zunstable-options -Z rustdoc-scrape-examples=all")
2505-
.masquerade_as_nightly_cargo()
2506-
.run();
2502+
p.cargo("doc").masquerade_as_nightly_cargo().run();
2503+
}
2504+
2505+
#[cargo_test]
2506+
fn scrape_examples_conflicting_reverse_deps() {
2507+
if !is_nightly() {
2508+
// -Z rustdoc-scrape-examples is unstable
2509+
return;
2510+
}
2511+
2512+
let p = project()
2513+
.file(
2514+
"Cargo.toml",
2515+
r#"
2516+
[package]
2517+
name = "foo"
2518+
version = "0.0.1"
2519+
authors = []
2520+
"#,
2521+
)
2522+
.file("src/lib.rs", "")
2523+
.file("examples/a.rs", "fn main() {}")
2524+
.file("benches/a.rs", "fn main() {}")
2525+
.build();
2526+
2527+
p.cargo("doc").masquerade_as_nightly_cargo().run();
2528+
2529+
println!("{}", p.root().display());
25072530
}
25082531

25092532
#[cargo_test]
@@ -2527,37 +2550,54 @@ fn scrape_examples_crate_with_dash() {
25272550
.file("examples/a.rs", "fn main() { da_sh::foo(); }")
25282551
.build();
25292552

2530-
p.cargo("doc -Zunstable-options -Z rustdoc-scrape-examples=all")
2531-
.masquerade_as_nightly_cargo()
2532-
.run();
2553+
p.cargo("doc").masquerade_as_nightly_cargo().run();
25332554

25342555
let doc_html = p.read_file("target/doc/da_sh/fn.foo.html");
25352556
assert!(doc_html.contains("Examples found in repository"));
25362557
}
25372558

25382559
#[cargo_test]
2539-
fn scrape_examples_missing_flag() {
2560+
fn scrape_examples_configure_target() {
25402561
if !is_nightly() {
2562+
// -Z rustdoc-scrape-examples is unstable
25412563
return;
25422564
}
25432565

25442566
let p = project()
25452567
.file(
25462568
"Cargo.toml",
25472569
r#"
2548-
[package]
2549-
name = "foo"
2550-
version = "1.2.4"
2551-
authors = []
2552-
"#,
2570+
[package]
2571+
name = "foo"
2572+
version = "0.0.1"
2573+
authors = []
2574+
2575+
[lib]
2576+
doc-scrape-examples = false
2577+
2578+
[[test]]
2579+
name = "a_test"
2580+
doc-scrape-examples = true
2581+
"#,
2582+
)
2583+
.file(
2584+
"src/lib.rs",
2585+
"pub fn foo() {} fn lib_must_not_appear() { foo(); }",
2586+
)
2587+
.file("examples/a.rs", "fn example_must_appear() { foo::foo(); }")
2588+
.file(
2589+
"tests/a_test.rs",
2590+
"#[test] fn test_must_appear() { foo::foo(); }",
25532591
)
2554-
.file("src/lib.rs", "//! These are the docs!")
25552592
.build();
2556-
p.cargo("doc -Zrustdoc-scrape-examples")
2557-
.masquerade_as_nightly_cargo()
2558-
.with_status(101)
2559-
.with_stderr("error: -Z rustdoc-scrape-examples must take [..] an argument")
2560-
.run();
2593+
2594+
p.cargo("doc").masquerade_as_nightly_cargo().run();
2595+
2596+
let doc_html = p.read_file("target/doc/foo/fn.foo.html");
2597+
println!("{}", doc_html);
2598+
assert!(!doc_html.contains("lib_must_not_appear"));
2599+
assert!(doc_html.contains("example_must_appear"));
2600+
assert!(doc_html.contains("test_must_appear"));
25612601
}
25622602

25632603
#[cargo_test]

0 commit comments

Comments
 (0)