Do not allow running library examples.
authorPatrik Svensson <patrik@patriksvensson.se>
Sat, 5 May 2018 08:39:51 +0000 (10:39 +0200)
committerPatrik Svensson <patrik@patriksvensson.se>
Sat, 5 May 2018 08:51:48 +0000 (10:51 +0200)
Closes #5474

src/cargo/core/compiler/context/mod.rs
src/cargo/ops/cargo_run.rs
tests/testsuite/run.rs

index a0e166860eac1be727989ef0ef9e2e22035a7b28..7c039fcca6bd16c3516e13c2621ae3129d38cfe6 100644 (file)
@@ -160,7 +160,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
                         unit.target.name().to_string(),
                         output.path.clone(),
                     ));
-                } else if unit.target.is_bin() || unit.target.is_example() {
+                } else if unit.target.is_bin() || unit.target.is_bin_example() {
                     self.compilation.binaries.push(bindst.clone());
                 } else if unit.target.is_lib() {
                     let pkgid = unit.pkg.package_id().clone();
index b609a0ea37679335ae9ff8373a8e3566aaf48676..7309b394d6ae6658d0ee761a563b06e303e6eac9 100644 (file)
@@ -2,7 +2,7 @@ use std::path::Path;
 
 use ops::{self, Packages};
 use util::{self, CargoResult, ProcessError};
-use core::Workspace;
+use core::{TargetKind, Workspace};
 
 pub fn run(
     ws: &Workspace,
@@ -26,7 +26,7 @@ pub fn run(
         },
     };
 
-    let bins: Vec<_> = pkg.manifest()
+let bins: Vec<_> = pkg.manifest()
         .targets()
         .iter()
         .filter(|a| {
@@ -36,7 +36,7 @@ pub fn run(
                 options.filter.target_run(a)
             }
         })
-        .map(|bin| bin.name())
+        .map(|bin| (bin.name(), bin.kind()))
         .collect();
 
     if bins.is_empty() {
@@ -46,13 +46,31 @@ pub fn run(
             // this will be verified in cargo_compile
         }
     }
+
+    if bins.len() == 1 {
+        let bin = bins.first().unwrap();
+        match *bin.1 {
+            TargetKind::ExampleLib(..) => { 
+                bail!(
+                    "example target `{}` is a library and cannot be executed.",
+                    bin.0
+                ) 
+            },
+            _ => { }
+        };
+    }
+
     if bins.len() > 1 {
         if !options.filter.is_specific() {
+
+            let names : Vec<&str> = bins.into_iter().map(|bin| bin.0).collect();
+
             bail!(
                 "`cargo run` requires that a project only have one \
                  executable; use the `--bin` option to specify which one \
-                 to run\navailable binaries: {}",
-                bins.join(", ")
+                 to run\navailable binaries: {}", 
+                 names.join(", ")
+                
             )
         } else {
             bail!(
@@ -86,4 +104,4 @@ pub fn run(
             Ok(Some(err))
         }
     }
-}
+}
\ No newline at end of file
index ac6c6e212d764cc3190d002d758557620abb4bf7..bf2e37fe2eead695721ba826621a6c54baad2c40 100644 (file)
@@ -387,6 +387,38 @@ fn run_example() {
     );
 }
 
+#[test]
+fn run_library_example() {
+    let p = project("foo")
+        .file(
+            "Cargo.toml",
+            r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+            [[example]]
+            name = "bar"
+            crate_type = ["lib"]
+        "#,
+        )
+        .file("src/lib.rs", "")
+        .file(
+            "examples/bar.rs",
+            r#"
+            fn foo() {}
+        "#,
+        )
+        .build();
+
+    assert_that(
+        p.cargo("run").arg("--example").arg("bar"),
+        execs()
+            .with_status(101)
+            .with_stderr("[ERROR] example target `bar` is a library and cannot be executed."),
+    );
+}
+
 fn autodiscover_examples_project(rust_edition: &str, autoexamples: Option<bool>) -> Project {
     let autoexamples = match autoexamples {
         None => "".to_string(),