diff --git a/src/cargo/core/profiles.rs b/src/cargo/core/profiles.rs index e9bca095a98..7bdd39712d0 100644 --- a/src/cargo/core/profiles.rs +++ b/src/cargo/core/profiles.rs @@ -1014,27 +1014,33 @@ fn merge_config_profiles( Some(profiles) => profiles.get_all().clone(), None => BTreeMap::new(), }; - // List of profile names to check if defined in config only. - let mut check_to_add = vec![requested_profile]; + // Set of profile names to check if defined in config only. + let mut check_to_add = HashSet::new(); + check_to_add.insert(requested_profile); // Merge config onto manifest profiles. for (name, profile) in &mut profiles { if let Some(config_profile) = get_config_profile(name, config, features)? { profile.merge(&config_profile); } if let Some(inherits) = &profile.inherits { - check_to_add.push(*inherits); + check_to_add.insert(*inherits); } } + // Add the built-in profiles. This is important for things like `cargo + // test` which implicitly use the "dev" profile for dependencies. + for name in &["dev", "release", "test", "bench"] { + check_to_add.insert(InternedString::new(name)); + } // Add config-only profiles. // Need to iterate repeatedly to get all the inherits values. - let mut current = Vec::new(); + let mut current = HashSet::new(); while !check_to_add.is_empty() { std::mem::swap(&mut current, &mut check_to_add); - for name in current.drain(..) { + for name in current.drain() { if !profiles.contains_key(&name) { if let Some(config_profile) = get_config_profile(&name, config, features)? { if let Some(inherits) = &config_profile.inherits { - check_to_add.push(*inherits); + check_to_add.insert(*inherits); } profiles.insert(name, config_profile); } diff --git a/tests/testsuite/profile_config.rs b/tests/testsuite/profile_config.rs index e9928c5ae5b..ce1f07557a0 100644 --- a/tests/testsuite/profile_config.rs +++ b/tests/testsuite/profile_config.rs @@ -1,6 +1,7 @@ //! Tests for profiles defined in config files. use cargo_test_support::paths::CargoPathExt; +use cargo_test_support::registry::Package; use cargo_test_support::{basic_lib_manifest, paths, project}; #[cargo_test] @@ -454,3 +455,38 @@ fn named_env_profile() { .with_stderr_contains("[..]-C codegen-units=1 [..]") .run(); } + +#[cargo_test] +fn test_with_dev_profile() { + // `cargo test` uses "dev" profile for dependencies. + Package::new("somedep", "1.0.0").publish(); + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + somedep = "1.0" + "#, + ) + .file("src/lib.rs", "") + .build(); + p.cargo("test --lib --no-run -v") + .env("CARGO_PROFILE_DEV_DEBUG", "0") + .with_stderr( + "\ +[UPDATING] [..] +[DOWNLOADING] [..] +[DOWNLOADED] [..] +[COMPILING] somedep v1.0.0 +[RUNNING] `rustc --crate-name somedep [..]-C debuginfo=0[..] +[COMPILING] foo v0.1.0 [..] +[RUNNING] `rustc --crate-name foo [..]-C debuginfo=2[..] +[FINISHED] [..] +", + ) + .run(); +}