Skip to content

Commit 935adb3

Browse files
committed
Clean up how doc tests are treated.
1 parent 6909178 commit 935adb3

File tree

9 files changed

+40
-22
lines changed

9 files changed

+40
-22
lines changed

src/cargo/core/compiler/build_config.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,16 +183,19 @@ impl CompileMode {
183183
}
184184
}
185185

186-
/// Returns `true` if this is a doc or doc test. Be careful using this.
187-
/// Although both run rustdoc, the dependencies for those two modes are
188-
/// very different.
186+
/// Returns `true` if this is generating documentation.
189187
pub fn is_doc(self) -> bool {
190188
match self {
191-
CompileMode::Doc { .. } | CompileMode::Doctest => true,
189+
CompileMode::Doc { .. } => true,
192190
_ => false,
193191
}
194192
}
195193

194+
/// Returns `true` if this a doc test.
195+
pub fn is_doc_test(self) -> bool {
196+
self == CompileMode::Doctest
197+
}
198+
196199
/// Returns `true` if this is any type of test (test, benchmark, doc test, or
197200
/// check test).
198201
pub fn is_any_test(self) -> bool {

src/cargo/core/compiler/context/compilation_files.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
146146
pub fn out_dir(&self, unit: &Unit<'a>) -> PathBuf {
147147
if unit.mode.is_doc() {
148148
self.layout(unit.kind).root().parent().unwrap().join("doc")
149+
} else if unit.mode.is_doc_test() {
150+
panic!("doc tests do not have an out dir");
149151
} else if unit.target.is_custom_build() {
150152
self.build_script_dir(unit)
151153
} else if unit.target.is_example() {
@@ -293,14 +295,12 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
293295
unit: &Unit<'a>,
294296
bcx: &BuildContext<'a, 'cfg>,
295297
) -> CargoResult<Arc<Vec<OutputFile>>> {
296-
let out_dir = self.out_dir(unit);
297-
298298
let ret = match unit.mode {
299299
CompileMode::Check { .. } => {
300300
// This may be confusing. rustc outputs a file named `lib*.rmeta`
301301
// for both libraries and binaries.
302302
let file_stem = self.file_stem(unit);
303-
let path = out_dir.join(format!("lib{}.rmeta", file_stem));
303+
let path = self.out_dir(unit).join(format!("lib{}.rmeta", file_stem));
304304
vec![OutputFile {
305305
path,
306306
hardlink: None,
@@ -309,7 +309,10 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
309309
}]
310310
}
311311
CompileMode::Doc { .. } => {
312-
let path = out_dir.join(unit.target.crate_name()).join("index.html");
312+
let path = self
313+
.out_dir(unit)
314+
.join(unit.target.crate_name())
315+
.join("index.html");
313316
vec![OutputFile {
314317
path,
315318
hardlink: None,
@@ -329,7 +332,7 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
329332
vec![]
330333
}
331334
CompileMode::Test | CompileMode::Build | CompileMode::Bench => {
332-
self.calc_outputs_rustc(unit, bcx, &out_dir)?
335+
self.calc_outputs_rustc(unit, bcx)?
333336
}
334337
};
335338
info!("Target filenames: {:?}", ret);
@@ -341,11 +344,11 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
341344
&self,
342345
unit: &Unit<'a>,
343346
bcx: &BuildContext<'a, 'cfg>,
344-
out_dir: &Path,
345347
) -> CargoResult<Vec<OutputFile>> {
346348
let mut ret = Vec::new();
347349
let mut unsupported = Vec::new();
348350

351+
let out_dir = self.out_dir(unit);
349352
let link_stem = self.link_stem(unit);
350353
let info = if unit.kind == Kind::Host {
351354
&bcx.host_info
@@ -468,6 +471,10 @@ fn compute_metadata<'a, 'cfg>(
468471
cx: &Context<'a, 'cfg>,
469472
metas: &mut HashMap<Unit<'a>, Option<Metadata>>,
470473
) -> Option<Metadata> {
474+
if unit.mode.is_doc_test() {
475+
// Doc tests do not have metadata.
476+
return None;
477+
}
471478
// No metadata for dylibs because of a couple issues:
472479
// - macOS encodes the dylib name in the executable,
473480
// - Windows rustc multiple files of which we can't easily link all of them.

src/cargo/core/compiler/context/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
166166
}
167167
}
168168

169-
if unit.mode == CompileMode::Doctest {
169+
if unit.mode.is_doc_test() {
170170
// Note that we can *only* doc-test rlib outputs here. A
171171
// staticlib output cannot be linked by the compiler (it just
172172
// doesn't do that). A dylib output, however, can be linked by

src/cargo/core/compiler/context/unit_dependencies.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ fn compute_deps<'a, 'cfg, 'tmp>(
129129
) -> CargoResult<Vec<(Unit<'a>, UnitFor)>> {
130130
if unit.mode.is_run_custom_build() {
131131
return compute_deps_custom_build(unit, state.cx.bcx);
132-
} else if unit.mode.is_doc() && !unit.mode.is_any_test() {
132+
} else if unit.mode.is_doc() {
133133
// Note: this does not include doc test.
134134
return compute_deps_doc(unit, state);
135135
}

src/cargo/core/compiler/fingerprint.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,8 @@ fn calculate<'a, 'cfg>(
10151015
}
10161016
let mut fingerprint = if unit.mode.is_run_custom_build() {
10171017
calculate_run_custom_build(cx, unit)?
1018+
} else if unit.mode.is_doc_test() {
1019+
panic!("doc tests do not fingerprint");
10181020
} else {
10191021
calculate_normal(cx, unit)?
10201022
};
@@ -1339,7 +1341,8 @@ fn write_fingerprint(loc: &Path, fingerprint: &Fingerprint) -> CargoResult<()> {
13391341
pub fn prepare_init<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoResult<()> {
13401342
let new1 = cx.files().fingerprint_dir(unit);
13411343

1342-
if fs::metadata(&new1).is_err() {
1344+
// Doc tests have no output, thus no fingerprint.
1345+
if !new1.exists() && !unit.mode.is_doc_test() {
13431346
fs::create_dir(&new1)?;
13441347
}
13451348

src/cargo/core/compiler/job_queue.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -596,11 +596,10 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
596596
// being a compiled package.
597597
Dirty => {
598598
if unit.mode.is_doc() {
599+
self.documented.insert(unit.pkg.package_id());
600+
config.shell().status("Documenting", unit.pkg)?;
601+
} else if unit.mode.is_doc_test() {
599602
// Skip doc test.
600-
if !unit.mode.is_any_test() {
601-
self.documented.insert(unit.pkg.package_id());
602-
config.shell().status("Documenting", unit.pkg)?;
603-
}
604603
} else {
605604
self.compiled.insert(unit.pkg.package_id());
606605
if unit.mode.is_check() {
@@ -613,8 +612,7 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
613612
Fresh => {
614613
// If doc test are last, only print "Fresh" if nothing has been printed.
615614
if self.counts[&unit.pkg.package_id()] == 0
616-
&& !(unit.mode == CompileMode::Doctest
617-
&& self.compiled.contains(&unit.pkg.package_id()))
615+
&& !(unit.mode.is_doc_test() && self.compiled.contains(&unit.pkg.package_id()))
618616
{
619617
self.compiled.insert(unit.pkg.package_id());
620618
config.shell().verbose(|c| c.status("Fresh", unit.pkg))?;

src/cargo/core/compiler/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ fn compile<'a, 'cfg: 'a>(
125125

126126
let job = if unit.mode.is_run_custom_build() {
127127
custom_build::prepare(cx, unit)?
128-
} else if unit.mode == CompileMode::Doctest {
128+
} else if unit.mode.is_doc_test() {
129129
// We run these targets later, so this is just a no-op for now.
130130
Job::new(Work::noop(), Freshness::Fresh)
131131
} else if build_plan {

src/cargo/ops/cargo_clean.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
104104
cx.prepare_units(None, &units)?;
105105

106106
for unit in units.iter() {
107+
if unit.mode.is_doc() || unit.mode.is_doc_test() {
108+
// Cleaning individual rustdoc crates is currently not supported.
109+
// For example, the search index would need to be rebuilt to fully
110+
// remove it (otherwise you're left with lots of broken links).
111+
// Doc tests produce no output.
112+
continue;
113+
}
107114
rm_rf(&cx.files().fingerprint_dir(unit), config)?;
108115
if unit.target.is_custom_build() {
109116
if unit.mode.is_run_custom_build() {

src/cargo/ops/cargo_compile.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ pub fn compile_ws<'a>(
383383
}
384384
if let Some(args) = local_rustdoc_args {
385385
for unit in &units {
386-
if unit.mode.is_doc() {
386+
if unit.mode.is_doc() || unit.mode.is_doc_test() {
387387
bcx.extra_compiler_args.insert(*unit, args.clone());
388388
}
389389
}
@@ -701,7 +701,7 @@ fn generate_targets<'a>(
701701
filter_targets(packages, Target::is_lib, false, bcx.build_config.mode)
702702
{
703703
let Proposal { target, pkg, .. } = proposal;
704-
if bcx.build_config.mode == CompileMode::Doctest && !target.doctestable() {
704+
if bcx.build_config.mode.is_doc_test() && !target.doctestable() {
705705
ws.config().shell().warn(format!(
706706
"doc tests are not supported for crate type(s) `{}` in package `{}`",
707707
target.rustc_crate_types().join(", "),

0 commit comments

Comments
 (0)