Skip to content

Commit 759431f

Browse files
committed
Auto merge of #7536 - ehuss:profile-override-warning-fix, r=alexcrichton
Fix profile override warning in a workspace. Profile overrides would erroneously warn about unused packages in a workspace if the package was not being built. The fix here is to retain the `Resolve` for the entire workspace, and use that to determine the valid set of packages. I think it would be good for a long-term goal to get rid of the second ("targeted") resolve. I'm still contemplating how a separate features resolver could achieve that, but it seems feasible long-term. Closes #7378
2 parents dcad4cc + 12392f6 commit 759431f

File tree

9 files changed

+103
-49
lines changed

9 files changed

+103
-49
lines changed

src/cargo/core/compiler/standard_lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ pub fn resolve_std<'cfg>(
103103
/*uses_default_features*/ true,
104104
);
105105
let resolve = ops::resolve_ws_with_opts(&std_ws, opts, &specs)?;
106-
Ok(resolve)
106+
Ok((resolve.pkg_set, resolve.targeted_resolve))
107107
}
108108

109109
/// Generate a list of root `Unit`s for the standard library.

src/cargo/core/profiles.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use serde::Deserialize;
66

77
use crate::core::compiler::{CompileMode, ProfileKind};
88
use crate::core::interning::InternedString;
9-
use crate::core::{Feature, Features, PackageId, PackageIdSpec, PackageSet, Shell};
9+
use crate::core::{Feature, Features, PackageId, PackageIdSpec, Resolve, Shell};
1010
use crate::util::errors::CargoResultExt;
1111
use crate::util::toml::{ProfilePackageSpec, StringOrBool, TomlProfile, TomlProfiles, U32OrBool};
1212
use crate::util::{closest_msg, CargoResult, Config};
@@ -429,13 +429,9 @@ impl Profiles {
429429
}
430430

431431
/// Used to check for overrides for non-existing packages.
432-
pub fn validate_packages(
433-
&self,
434-
shell: &mut Shell,
435-
packages: &PackageSet<'_>,
436-
) -> CargoResult<()> {
432+
pub fn validate_packages(&self, shell: &mut Shell, resolve: &Resolve) -> CargoResult<()> {
437433
for profile in self.by_name.values() {
438-
profile.validate_packages(shell, packages)?;
434+
profile.validate_packages(shell, resolve)?;
439435
}
440436
Ok(())
441437
}
@@ -502,16 +498,16 @@ impl ProfileMaker {
502498
profile
503499
}
504500

505-
fn validate_packages(&self, shell: &mut Shell, packages: &PackageSet<'_>) -> CargoResult<()> {
506-
self.validate_packages_toml(shell, packages, &self.toml, true)?;
507-
self.validate_packages_toml(shell, packages, &self.config, false)?;
501+
fn validate_packages(&self, shell: &mut Shell, resolve: &Resolve) -> CargoResult<()> {
502+
self.validate_packages_toml(shell, resolve, &self.toml, true)?;
503+
self.validate_packages_toml(shell, resolve, &self.config, false)?;
508504
Ok(())
509505
}
510506

511507
fn validate_packages_toml(
512508
&self,
513509
shell: &mut Shell,
514-
packages: &PackageSet<'_>,
510+
resolve: &Resolve,
515511
toml: &Option<TomlProfile>,
516512
warn_unmatched: bool,
517513
) -> CargoResult<()> {
@@ -525,7 +521,7 @@ impl ProfileMaker {
525521
};
526522
// Verify that a package doesn't match multiple spec overrides.
527523
let mut found = HashSet::new();
528-
for pkg_id in packages.package_ids() {
524+
for pkg_id in resolve.iter() {
529525
let matches: Vec<&PackageIdSpec> = overrides
530526
.keys()
531527
.filter_map(|key| match *key {
@@ -575,8 +571,8 @@ impl ProfileMaker {
575571
});
576572
for spec in missing_specs {
577573
// See if there is an exact name match.
578-
let name_matches: Vec<String> = packages
579-
.package_ids()
574+
let name_matches: Vec<String> = resolve
575+
.iter()
580576
.filter_map(|pkg_id| {
581577
if pkg_id.name() == spec.name() {
582578
Some(pkg_id.to_string())
@@ -586,8 +582,7 @@ impl ProfileMaker {
586582
})
587583
.collect();
588584
if name_matches.is_empty() {
589-
let suggestion =
590-
closest_msg(&spec.name(), packages.package_ids(), |p| p.name().as_str());
585+
let suggestion = closest_msg(&spec.name(), resolve.iter(), |p| p.name().as_str());
591586
shell.warn(format!(
592587
"package profile spec `{}` did not match any packages{}",
593588
spec, suggestion

src/cargo/ops/cargo_compile.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use crate::core::resolver::{Resolve, ResolveOpts};
3838
use crate::core::{LibKind, Package, PackageSet, Target};
3939
use crate::core::{PackageId, PackageIdSpec, TargetKind, Workspace};
4040
use crate::ops;
41+
use crate::ops::resolve::WorkspaceResolve;
4142
use crate::util::config::Config;
4243
use crate::util::{closest_msg, profile, CargoResult};
4344

@@ -303,7 +304,11 @@ pub fn compile_ws<'a>(
303304
let dev_deps = ws.require_optional_deps() || filter.need_dev_deps(build_config.mode);
304305
let opts = ResolveOpts::new(dev_deps, features, all_features, !no_default_features);
305306
let resolve = ops::resolve_ws_with_opts(ws, opts, &specs)?;
306-
let (mut packages, resolve_with_overrides) = resolve;
307+
let WorkspaceResolve {
308+
mut pkg_set,
309+
workspace_resolve,
310+
targeted_resolve: resolve,
311+
} = resolve;
307312

308313
let std_resolve = if let Some(crates) = &config.cli_unstable().build_std {
309314
if build_config.build_plan {
@@ -319,7 +324,7 @@ pub fn compile_ws<'a>(
319324
}
320325
let (mut std_package_set, std_resolve) = standard_lib::resolve_std(ws, crates)?;
321326
remove_dylib_crate_type(&mut std_package_set)?;
322-
packages.add_set(std_package_set);
327+
pkg_set.add_set(std_package_set);
323328
Some(std_resolve)
324329
} else {
325330
None
@@ -330,12 +335,12 @@ pub fn compile_ws<'a>(
330335
// Vec<PackageIdSpec> to a Vec<&PackageId>.
331336
let to_build_ids = specs
332337
.iter()
333-
.map(|s| s.query(resolve_with_overrides.iter()))
338+
.map(|s| s.query(resolve.iter()))
334339
.collect::<CargoResult<Vec<_>>>()?;
335340
// Now get the `Package` for each `PackageId`. This may trigger a download
336341
// if the user specified `-p` for a dependency that is not downloaded.
337342
// Dependencies will be downloaded during build_unit_dependencies.
338-
let mut to_builds = packages.get_many(to_build_ids)?;
343+
let mut to_builds = pkg_set.get_many(to_build_ids)?;
339344

340345
// The ordering here affects some error messages coming out of cargo, so
341346
// let's be test and CLI friendly by always printing in the same order if
@@ -370,12 +375,15 @@ pub fn compile_ws<'a>(
370375
);
371376
}
372377

373-
profiles.validate_packages(&mut config.shell(), &packages)?;
378+
profiles.validate_packages(
379+
&mut config.shell(),
380+
workspace_resolve.as_ref().unwrap_or(&resolve),
381+
)?;
374382

375383
let interner = UnitInterner::new();
376384
let mut bcx = BuildContext::new(
377385
ws,
378-
&packages,
386+
&pkg_set,
379387
config,
380388
build_config,
381389
profiles,
@@ -388,7 +396,7 @@ pub fn compile_ws<'a>(
388396
&to_builds,
389397
filter,
390398
build_config.requested_kind,
391-
&resolve_with_overrides,
399+
&resolve,
392400
&bcx,
393401
)?;
394402

@@ -434,13 +442,8 @@ pub fn compile_ws<'a>(
434442
}
435443
}
436444

437-
let unit_dependencies = build_unit_dependencies(
438-
&bcx,
439-
&resolve_with_overrides,
440-
std_resolve.as_ref(),
441-
&units,
442-
&std_roots,
443-
)?;
445+
let unit_dependencies =
446+
build_unit_dependencies(&bcx, &resolve, std_resolve.as_ref(), &units, &std_roots)?;
444447

445448
let ret = {
446449
let _p = profile::start("compiling");

src/cargo/ops/cargo_doc.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,13 @@ pub fn doc(ws: &Workspace<'_>, options: &DocOptions<'_>) -> CargoResult<()> {
2424
options.compile_opts.all_features,
2525
!options.compile_opts.no_default_features,
2626
);
27-
let resolve = ops::resolve_ws_with_opts(ws, opts, &specs)?;
28-
let (packages, resolve_with_overrides) = resolve;
27+
let ws_resolve = ops::resolve_ws_with_opts(ws, opts, &specs)?;
2928

3029
let ids = specs
3130
.iter()
32-
.map(|s| s.query(resolve_with_overrides.iter()))
31+
.map(|s| s.query(ws_resolve.targeted_resolve.iter()))
3332
.collect::<CargoResult<Vec<_>>>()?;
34-
let pkgs = packages.get_many(ids)?;
33+
let pkgs = ws_resolve.pkg_set.get_many(ids)?;
3534

3635
let mut lib_names = HashMap::new();
3736
let mut bin_names = HashMap::new();

src/cargo/ops/cargo_install.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -491,14 +491,14 @@ fn check_yanked_install(ws: &Workspace<'_>) -> CargoResult<()> {
491491
// It would be best if `source` could be passed in here to avoid a
492492
// duplicate "Updating", but since `source` is taken by value, then it
493493
// wouldn't be available for `compile_ws`.
494-
let (pkg_set, resolve) = ops::resolve_ws_with_opts(ws, ResolveOpts::everything(), &specs)?;
495-
let mut sources = pkg_set.sources_mut();
494+
let ws_resolve = ops::resolve_ws_with_opts(ws, ResolveOpts::everything(), &specs)?;
495+
let mut sources = ws_resolve.pkg_set.sources_mut();
496496

497497
// Checking the yanked status involves taking a look at the registry and
498498
// maybe updating files, so be sure to lock it here.
499499
let _lock = ws.config().acquire_package_cache_lock()?;
500500

501-
for pkg_id in resolve.iter() {
501+
for pkg_id in ws_resolve.targeted_resolve.iter() {
502502
if let Some(source) = sources.get_mut(pkg_id.source_id()) {
503503
if source.is_yanked(pkg_id)? {
504504
ws.config().shell().warn(format!(

src/cargo/ops/cargo_output_metadata.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,17 +56,20 @@ fn metadata_full(ws: &Workspace<'_>, opt: &OutputMetadataOptions) -> CargoResult
5656
opt.all_features,
5757
!opt.no_default_features,
5858
);
59-
let (package_set, resolve) = ops::resolve_ws_with_opts(ws, opts, &specs)?;
59+
let ws_resolve = ops::resolve_ws_with_opts(ws, opts, &specs)?;
6060
let mut packages = HashMap::new();
61-
for pkg in package_set.get_many(package_set.package_ids())? {
61+
for pkg in ws_resolve
62+
.pkg_set
63+
.get_many(ws_resolve.pkg_set.package_ids())?
64+
{
6265
packages.insert(pkg.package_id(), pkg.clone());
6366
}
6467

6568
Ok(ExportInfo {
6669
packages: packages.values().map(|p| (*p).clone()).collect(),
6770
workspace_members: ws.members().map(|pkg| pkg.package_id()).collect(),
6871
resolve: Some(MetadataResolve {
69-
resolve: (packages, resolve),
72+
resolve: (packages, ws_resolve.targeted_resolve),
7073
root: ws.current_opt().map(|pkg| pkg.package_id()),
7174
}),
7275
target_directory: ws.target_dir().into_path_unlocked(),

src/cargo/ops/cargo_package.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,15 +155,19 @@ fn build_lock(ws: &Workspace<'_>) -> CargoResult<String> {
155155
// Regenerate Cargo.lock using the old one as a guide.
156156
let specs = vec![PackageIdSpec::from_package_id(new_pkg.package_id())];
157157
let tmp_ws = Workspace::ephemeral(new_pkg, ws.config(), None, true)?;
158-
let (pkg_set, new_resolve) =
159-
ops::resolve_ws_with_opts(&tmp_ws, ResolveOpts::everything(), &specs)?;
158+
let new_resolve = ops::resolve_ws_with_opts(&tmp_ws, ResolveOpts::everything(), &specs)?;
160159

161160
if let Some(orig_resolve) = orig_resolve {
162-
compare_resolve(config, tmp_ws.current()?, &orig_resolve, &new_resolve)?;
161+
compare_resolve(
162+
config,
163+
tmp_ws.current()?,
164+
&orig_resolve,
165+
&new_resolve.targeted_resolve,
166+
)?;
163167
}
164-
check_yanked(config, &pkg_set, &new_resolve)?;
168+
check_yanked(config, &new_resolve.pkg_set, &new_resolve.targeted_resolve)?;
165169

166-
ops::resolve_to_string(&tmp_ws, &new_resolve)
170+
ops::resolve_to_string(&tmp_ws, &new_resolve.targeted_resolve)
167171
}
168172

169173
// Checks that the package has some piece of metadata that a human can

src/cargo/ops/resolve.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,20 @@ use crate::sources::PathSource;
2424
use crate::util::errors::{CargoResult, CargoResultExt};
2525
use crate::util::profile;
2626

27+
/// Result for `resolve_ws_with_opts`.
28+
pub struct WorkspaceResolve<'a> {
29+
/// Packages to be downloaded.
30+
pub pkg_set: PackageSet<'a>,
31+
/// The resolve for the entire workspace.
32+
///
33+
/// This may be `None` for things like `cargo install` and `-Zavoid-dev-deps`.
34+
/// This does not include `paths` overrides.
35+
pub workspace_resolve: Option<Resolve>,
36+
/// The narrowed resolve, with the specific features enabled, and only the
37+
/// given package specs requested.
38+
pub targeted_resolve: Resolve,
39+
}
40+
2741
const UNUSED_PATCH_WARNING: &str = "\
2842
Check that the patched package version and available features are compatible
2943
with the dependency requirements. If the patch has a different version from
@@ -60,7 +74,7 @@ pub fn resolve_ws_with_opts<'a>(
6074
ws: &Workspace<'a>,
6175
opts: ResolveOpts,
6276
specs: &[PackageIdSpec],
63-
) -> CargoResult<(PackageSet<'a>, Resolve)> {
77+
) -> CargoResult<WorkspaceResolve<'a>> {
6478
let mut registry = PackageRegistry::new(ws.config())?;
6579
let mut add_patches = true;
6680

@@ -106,9 +120,13 @@ pub fn resolve_ws_with_opts<'a>(
106120
add_patches,
107121
)?;
108122

109-
let packages = get_resolved_packages(&resolved_with_overrides, registry)?;
123+
let pkg_set = get_resolved_packages(&resolved_with_overrides, registry)?;
110124

111-
Ok((packages, resolved_with_overrides))
125+
Ok(WorkspaceResolve {
126+
pkg_set,
127+
workspace_resolve: resolve,
128+
targeted_resolve: resolved_with_overrides,
129+
})
112130
}
113131

114132
fn resolve_with_registry<'cfg>(

tests/testsuite/profile_overrides.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,3 +512,35 @@ fn override_package_rename() {
512512
")
513513
.run();
514514
}
515+
516+
#[cargo_test]
517+
fn no_warning_ws() {
518+
// https://github.com/rust-lang/cargo/issues/7378, avoid warnings in a workspace.
519+
let p = project()
520+
.file(
521+
"Cargo.toml",
522+
r#"
523+
cargo-features = ["profile-overrides"]
524+
[workspace]
525+
members = ["a", "b"]
526+
527+
[profile.dev.package.a]
528+
codegen-units = 3
529+
"#,
530+
)
531+
.file("a/Cargo.toml", &basic_manifest("a", "0.1.0"))
532+
.file("a/src/lib.rs", "")
533+
.file("b/Cargo.toml", &basic_manifest("b", "0.1.0"))
534+
.file("b/src/lib.rs", "")
535+
.build();
536+
537+
p.cargo("build -p b")
538+
.masquerade_as_nightly_cargo()
539+
.with_stderr(
540+
"\
541+
[COMPILING] b [..]
542+
[FINISHED] [..]
543+
",
544+
)
545+
.run();
546+
}

0 commit comments

Comments
 (0)