diff --git a/src/internal/core.rs b/src/internal/core.rs index a61eba0d..d6fd1040 100644 --- a/src/internal/core.rs +++ b/src/internal/core.rs @@ -96,6 +96,38 @@ impl State { self.merge_incompatibility(id); } + /// Add a single custom incompatibility that requires the base package and the proxy package + /// share the same version range. + /// + /// This intended for cases where proxy packages (also known as virtual packages) are used. + /// Without this information, pubgrub does not know that these packages have to be at the same + /// version. In cases where the base package is already to an incompatible version, this avoids + /// going through all versions of the proxy package. In cases where there are two incompatible + /// proxy packages, it avoids trying versions for both of them. Both improve performance (we + /// don't need to check all versions when there is a conflict) and error messages (report a + /// conflict of version ranges instead of enumerating the conflicting versions). + /// + /// Using this method requires that each version of the proxy package depends on the exact + /// version of the base package. + pub fn add_proxy_package( + &mut self, + proxy_package: Id, + base_package: Id, + versions: DP::VS, + ) { + let incompat = Incompatibility::from_dependency( + proxy_package, + versions.clone(), + (base_package, versions), + ); + let id = self + .incompatibility_store + .alloc_iter([incompat].into_iter()); + for id in IncompDpId::::range_to_iter(id) { + self.merge_incompatibility(id); + } + } + /// Add an incompatibility to the state. #[cold] pub(crate) fn add_incompatibility_from_dependencies(