diff --git a/src/cargo/util/toml/targets.rs b/src/cargo/util/toml/targets.rs index 473994b285d..af98bc7469d 100644 --- a/src/cargo/util/toml/targets.rs +++ b/src/cargo/util/toml/targets.rs @@ -215,6 +215,15 @@ fn clean_lib( // A plugin requires exporting plugin_registrar so a crate cannot be // both at once. let crate_types = match (lib.crate_types(), lib.plugin, lib.proc_macro()) { + (Some(kinds), _, _) + if kinds.contains(&CrateType::Dylib.as_str().to_owned()) + && kinds.contains(&CrateType::Cdylib.as_str().to_owned()) => + { + anyhow::bail!(format!( + "library `{}` cannot set the crate type of both `dylib` and `cdylib`", + lib.name() + )); + } (Some(kinds), _, _) if kinds.contains(&"proc-macro".to_string()) => { if let Some(true) = lib.plugin { // This is a warning to retain backwards compatibility. diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index ce45f41a218..091cb548bf4 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -1633,6 +1633,39 @@ fn many_crate_types_correct() { assert!(p.root().join("target/debug").join(&fname).is_file()); } +#[cargo_test] +fn set_both_dylib_and_cdylib_crate_types() { + let p = project() + .file( + "Cargo.toml", + r#" + [project] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [lib] + + name = "foo" + crate_type = ["cdylib", "dylib"] + "#, + ) + .file("src/lib.rs", "pub fn foo() {}") + .build(); + p.cargo("build") + .with_status(101) + .with_stderr( + "\ +error: failed to parse manifest at `[..]` + +Caused by: + library `foo` cannot set the crate type of both `dylib` and `cdylib` +", + ) + .run(); +} + #[cargo_test] fn self_dependency() { let p = project()