diff --git a/src/cargo/core/compiler/build_config.rs b/src/cargo/core/compiler/build_config.rs index 00733f38ab8..3770bb68c54 100644 --- a/src/cargo/core/compiler/build_config.rs +++ b/src/cargo/core/compiler/build_config.rs @@ -219,4 +219,15 @@ impl CompileMode { pub fn is_run_custom_build(self) -> bool { self == CompileMode::RunCustomBuild } + + /// Returns `true` if this mode may generate an executable. + /// + /// Note that this also returns `true` for building libraries, so you also + /// have to check the target. + pub fn generates_executable(self) -> bool { + matches!( + self, + CompileMode::Test | CompileMode::Bench | CompileMode::Build + ) + } } diff --git a/src/cargo/core/compiler/context/mod.rs b/src/cargo/core/compiler/context/mod.rs index 47f21c9b6dd..7591c7d3d2d 100644 --- a/src/cargo/core/compiler/context/mod.rs +++ b/src/cargo/core/compiler/context/mod.rs @@ -294,19 +294,16 @@ impl<'a, 'cfg> Context<'a, 'cfg> { /// Returns the executable for the specified unit (if any). pub fn get_executable(&mut self, unit: &Unit) -> CargoResult> { - for output in self.outputs(unit)?.iter() { - if output.flavor != FileFlavor::Normal { - continue; - } - - let is_binary = unit.target.is_executable(); - let is_test = unit.mode.is_any_test() && !unit.mode.is_check(); - - if is_binary || is_test { - return Ok(Option::Some(output.bin_dst().clone())); - } + let is_binary = unit.target.is_executable(); + let is_test = unit.mode.is_any_test(); + if !unit.mode.generates_executable() || !(is_binary || is_test) { + return Ok(None); } - Ok(None) + Ok(self + .outputs(unit)? + .iter() + .find(|o| o.flavor == FileFlavor::Normal) + .map(|output| output.bin_dst().clone())) } pub fn prepare_units(&mut self) -> CargoResult<()> { diff --git a/tests/testsuite/doc.rs b/tests/testsuite/doc.rs index 4e5e6e68db4..f60f1af4b29 100644 --- a/tests/testsuite/doc.rs +++ b/tests/testsuite/doc.rs @@ -1638,6 +1638,89 @@ fn doc_message_format() { .run(); } +#[cargo_test] +fn doc_json_artifacts() { + // Checks the output of json artifact messages. + let p = project() + .file("src/lib.rs", "") + .file("src/bin/somebin.rs", "fn main() {}") + .build(); + + p.cargo("doc --message-format=json") + .with_json_contains_unordered( + r#" +{ + "reason": "compiler-artifact", + "package_id": "foo 0.0.1 [..]", + "manifest_path": "[ROOT]/foo/Cargo.toml", + "target": + { + "kind": ["lib"], + "crate_types": ["lib"], + "name": "foo", + "src_path": "[ROOT]/foo/src/lib.rs", + "edition": "2015", + "doc": true, + "doctest": true, + "test": true + }, + "profile": "{...}", + "features": [], + "filenames": ["[ROOT]/foo/target/debug/deps/libfoo-[..].rmeta"], + "executable": null, + "fresh": false +} + +{ + "reason": "compiler-artifact", + "package_id": "foo 0.0.1 [..]", + "manifest_path": "[ROOT]/foo/Cargo.toml", + "target": + { + "kind": ["lib"], + "crate_types": ["lib"], + "name": "foo", + "src_path": "[ROOT]/foo/src/lib.rs", + "edition": "2015", + "doc": true, + "doctest": true, + "test": true + }, + "profile": "{...}", + "features": [], + "filenames": ["[ROOT]/foo/target/doc/foo/index.html"], + "executable": null, + "fresh": false +} + +{ + "reason": "compiler-artifact", + "package_id": "foo 0.0.1 [..]", + "manifest_path": "[ROOT]/foo/Cargo.toml", + "target": + { + "kind": ["bin"], + "crate_types": ["bin"], + "name": "somebin", + "src_path": "[ROOT]/foo/src/bin/somebin.rs", + "edition": "2015", + "doc": true, + "doctest": false, + "test": true + }, + "profile": "{...}", + "features": [], + "filenames": ["[ROOT]/foo/target/doc/somebin/index.html"], + "executable": null, + "fresh": false +} + +{"reason":"build-finished","success":true} +"#, + ) + .run(); +} + #[cargo_test] fn short_message_format() { let p = project().file("src/lib.rs", BAD_INTRA_LINK_LIB).build();