diff --git a/src/cargo/ops/resolve.rs b/src/cargo/ops/resolve.rs index a6debf82d..fe2ec3964 100644 --- a/src/cargo/ops/resolve.rs +++ b/src/cargo/ops/resolve.rs @@ -10,6 +10,12 @@ use crate::sources::PathSource; use crate::util::errors::{CargoResult, CargoResultExt}; use crate::util::profile; +const UNUSED_PATCH_WARNING: &str = "\ +Check that the patched package version and available features are compatible +with the dependency requirements. If the patch has a different version from +what is locked in the Cargo.lock file, run `cargo update` to use the new +version. This may also occur with an optional dependency that is not enabled."; + /// Resolve all dependencies for the workspace using the previous /// lockfile as a guide if present. /// @@ -334,6 +340,24 @@ pub fn resolve_with_previous<'cfg>( warn, )?; resolved.register_used_patches(registry.patches()); + if warn { + // It would be good if this warning was more targeted and helpful + // (such as showing close candidates that failed to match). However, + // that's not terribly easy to do, so just show a general help + // message. + let warnings: Vec = resolved + .unused_patches() + .iter() + .map(|pkgid| format!("Patch `{}` was not used in the crate graph.", pkgid)) + .collect(); + if !warnings.is_empty() { + ws.config().shell().warn(format!( + "{}\n{}", + warnings.join("\n"), + UNUSED_PATCH_WARNING + ))?; + } + } if let Some(previous) = previous { resolved.merge_from(previous)?; } diff --git a/tests/testsuite/patch.rs b/tests/testsuite/patch.rs index 4d4498b11..11f5d7948 100644 --- a/tests/testsuite/patch.rs +++ b/tests/testsuite/patch.rs @@ -232,6 +232,11 @@ fn unused() { .with_stderr( "\ [UPDATING] `[ROOT][..]` index +[WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph. +[..] +[..] +[..] +[..] [DOWNLOADING] crates ... [DOWNLOADED] bar v0.1.0 [..] [COMPILING] bar v0.1.0 @@ -240,7 +245,18 @@ fn unused() { ", ) .run(); - p.cargo("build").with_stderr("[FINISHED] [..]").run(); + p.cargo("build") + .with_stderr( + "\ +[WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph. +[..] +[..] +[..] +[..] +[FINISHED] [..] +", + ) + .run(); // unused patch should be in the lock file let mut lock = String::new(); @@ -293,6 +309,11 @@ fn unused_git() { "\ [UPDATING] git repository `file://[..]` [UPDATING] `[ROOT][..]` index +[WARNING] Patch `bar v0.2.0 ([..])` was not used in the crate graph. +[..] +[..] +[..] +[..] [DOWNLOADING] crates ... [DOWNLOADED] bar v0.1.0 [..] [COMPILING] bar v0.1.0 @@ -301,7 +322,18 @@ fn unused_git() { ", ) .run(); - p.cargo("build").with_stderr("[FINISHED] [..]").run(); + p.cargo("build") + .with_stderr( + "\ +[WARNING] Patch `bar v0.2.0 ([..])` was not used in the crate graph. +[..] +[..] +[..] +[..] +[FINISHED] [..] +", + ) + .run(); } #[test] @@ -419,9 +451,38 @@ fn add_ignored_patch() { )); p.cargo("build") - .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]") + .with_stderr( + "\ +[WARNING] Patch `bar v0.1.1 ([CWD]/bar)` was not used in the crate graph. +[..] +[..] +[..] +[..] +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]", + ) + .run(); + p.cargo("build") + .with_stderr( + "\ +[WARNING] Patch `bar v0.1.1 ([CWD]/bar)` was not used in the crate graph. +[..] +[..] +[..] +[..] +[FINISHED] [..]", + ) + .run(); + + p.cargo("update").run(); + p.cargo("build") + .with_stderr( + "\ +[COMPILING] bar v0.1.1 ([CWD]/bar) +[COMPILING] foo v0.0.1 ([CWD]) +[FINISHED] dev [..] +", + ) .run(); - p.cargo("build").with_stderr("[FINISHED] [..]").run(); } #[test]