From 54ee781b934d3d8e0cb875b9fe30eaeb35bd7be6 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Wed, 6 Aug 2025 00:37:17 +0000 Subject: [PATCH] Support profile overrides for `-Z build-std` Pass both the main package graph and the build-std package graph to the verifier so that e.g. `[profile.dev.package.core]` is not rejected and ignored if `core` is being built. --- src/cargo/core/profiles.rs | 33 +++++++++------------- src/cargo/ops/cargo_compile/mod.rs | 13 +++++---- tests/testsuite/standard_lib.rs | 44 ++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 25 deletions(-) diff --git a/src/cargo/core/profiles.rs b/src/cargo/core/profiles.rs index 3c4c457c158..04a090f4207 100644 --- a/src/cargo/core/profiles.rs +++ b/src/cargo/core/profiles.rs @@ -25,9 +25,7 @@ use crate::core::Feature; use crate::core::compiler::{CompileKind, CompileTarget, Unit}; use crate::core::dependency::Artifact; use crate::core::resolver::features::FeaturesFor; -use crate::core::{ - PackageId, PackageIdSpec, PackageIdSpecQuery, Resolve, Shell, Target, Workspace, -}; +use crate::core::{PackageId, PackageIdSpec, PackageIdSpecQuery, Shell, Target, Workspace}; use crate::util::interning::InternedString; use crate::util::toml::validate_profile; use crate::util::{CargoResult, GlobalContext, closest_msg, context}; @@ -352,11 +350,11 @@ impl Profiles { } /// Used to check for overrides for non-existing packages. - pub fn validate_packages( + pub fn validate_packages>( &self, profiles: Option<&TomlProfiles>, shell: &mut Shell, - resolve: &Resolve, + packages: impl Fn() -> I, ) -> CargoResult<()> { for (name, profile) in &self.by_name { // If the user did not specify an override, skip this. This is here @@ -372,13 +370,13 @@ impl Profiles { { continue; } - let found = validate_packages_unique(resolve, name, &profile.toml)?; + let found = validate_packages_unique(&packages, name, &profile.toml)?; // We intentionally do not validate unmatched packages for config // profiles, in case they are defined in a central location. This // iterates over the manifest profiles only. if let Some(profiles) = profiles { if let Some(toml_profile) = profiles.get(name) { - validate_packages_unmatched(shell, resolve, name, toml_profile, &found)?; + validate_packages_unmatched(shell, &packages, name, toml_profile, &found)?; } } } @@ -1335,8 +1333,8 @@ fn get_config_profile(ws: &Workspace<'_>, name: &str) -> CargoResult>( + packages: impl Fn() -> I, name: &str, toml: &Option, ) -> CargoResult> { @@ -1348,7 +1346,7 @@ fn validate_packages_unique( }; // Verify that a package doesn't match multiple spec overrides. let mut found = HashSet::new(); - for pkg_id in resolve.iter() { + for pkg_id in packages() { let matches: Vec<&PackageIdSpec> = overrides .keys() .filter_map(|key| match *key { @@ -1389,9 +1387,9 @@ fn validate_packages_unique( /// Check for any profile override specs that do not match any known packages. /// /// This helps check for typos and mistakes. -fn validate_packages_unmatched( +fn validate_packages_unmatched>( shell: &mut Shell, - resolve: &Resolve, + packages: impl Fn() -> I, name: &str, toml: &TomlProfile, found: &HashSet, @@ -1411,8 +1409,7 @@ fn validate_packages_unmatched( }); for spec in missing_specs { // See if there is an exact name match. - let name_matches: Vec = resolve - .iter() + let name_matches: Vec = packages() .filter_map(|pkg_id| { if pkg_id.name() == spec.name() { Some(pkg_id.to_string()) @@ -1422,12 +1419,8 @@ fn validate_packages_unmatched( }) .collect(); if name_matches.is_empty() { - let suggestion = closest_msg( - &spec.name(), - resolve.iter(), - |p| p.name().as_str(), - "package", - ); + let suggestion = + closest_msg(&spec.name(), packages(), |p| p.name().as_str(), "package"); shell.warn(format!( "profile package spec `{}` in profile `{}` did not match any packages{}", spec, name, suggestion diff --git a/src/cargo/ops/cargo_compile/mod.rs b/src/cargo/ops/cargo_compile/mod.rs index 0e79a7ac1f0..99f4147d4b8 100644 --- a/src/cargo/ops/cargo_compile/mod.rs +++ b/src/cargo/ops/cargo_compile/mod.rs @@ -344,11 +344,14 @@ pub fn create_bcx<'a, 'gctx>( } let profiles = Profiles::new(ws, build_config.requested_profile)?; - profiles.validate_packages( - ws.profiles(), - &mut gctx.shell(), - workspace_resolve.as_ref().unwrap_or(&resolve), - )?; + let pkg_resolve = workspace_resolve.as_ref().unwrap_or(&resolve); + if let Some((std_resolve, _)) = &std_resolve_features { + profiles.validate_packages(ws.profiles(), &mut gctx.shell(), || { + pkg_resolve.iter().chain(std_resolve.iter()) + })? + } else { + profiles.validate_packages(ws.profiles(), &mut gctx.shell(), || pkg_resolve.iter())? + }; // If `--target` has not been specified, then the unit graph is built // assuming `--target $HOST` was specified. See diff --git a/tests/testsuite/standard_lib.rs b/tests/testsuite/standard_lib.rs index d228a42211b..660db7c697e 100644 --- a/tests/testsuite/standard_lib.rs +++ b/tests/testsuite/standard_lib.rs @@ -866,3 +866,47 @@ fn fetch() { .with_stderr_does_not_contain("[DOWNLOADED] [..]") .run(); } + +#[cargo_test(build_std_mock)] +fn core_profile() { + let setup = setup(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "profile-check" + edition = "2024" + + [profile.dev.package.core] + debug-assertions = false + "#, + ) + .file("src/lib.rs", "extern crate core;") + .build(); + p.cargo("build -v") + .build_std_arg(&setup, "compiler_builtins,core") + .with_stderr_data( + str![[r#" +[UPDATING] `dummy-registry` index +[DOWNLOADING] crates ... +[DOWNLOADED] registry-dep-using-std v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] registry-dep-using-core v1.0.0 (registry `dummy-registry`) +[DOWNLOADED] registry-dep-using-alloc v1.0.0 (registry `dummy-registry`) +[COMPILING] compiler_builtins v0.1.0 ([..]/library/compiler_builtins) +[COMPILING] core v0.1.0 ([..]/library/core) +[COMPILING] profile-check v0.0.0 ([ROOT]/foo) +[RUNNING] `[..] rustc --crate-name compiler_builtins [..]` +[RUNNING] `[..] rustc --crate-name core [..] -C debug-assertions=off [..]` +[RUNNING] `[..] rustc --crate-name profile_check [..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]] + .unordered(), + ) + .with_stderr_does_not_contain( + "[RUNNING] `[..] rustc --crate-name compiler_builtins [..] -C debug-assertions=off [..]`", + ) + .run(); +}