#cyclic #md #details #order #set #demonstrate #crate-level

depcycle-x

Example of a crate-level cyclic dependency; see README.md for details

3 releases (stable)

1.0.1 Sep 19, 2021
0.1.0 Sep 19, 2021

#429 in Operating systems

Download history 1/week @ 2024-02-14 7/week @ 2024-02-21 4/week @ 2024-02-28 1/week @ 2024-03-13 28/week @ 2024-03-27 30/week @ 2024-04-03

58 downloads per month
Used in depcycle-y

MIT/Apache

4KB

What's this?

This crate demonstrates a crate-level cyclic dependency in Cargo.

Cargo enforces acyclicity on the feature-level not the crate-level [1], and therefore it is trivially possible to create cyclic dependencies on the crate-level.

This is an instance of the general theorem that when you have a partial order defined on a set B, and a non-injective surjective mapping F from that set to another strictly smaller set S, then an ordering on S defined as

s0 <= s1 iff exists b0 <= b1 where F(b0) = s0 and F(b1) = s1

is not always a partial order, but is a pre-order that may contain cycles.

(This is related to various impossibility results on voting systems.)

Consequences

As applied to package managers:

  • B is "the set of crate features" or "the set of binary packages"
  • the ordering on B is the feature-level or binary-level dependency ordering
  • S is "the set of crates" or "the set of source packages"
  • the ordering on S is the crate-level or source-level dependency ordering

Cargo does not use the ordering on S, and therefore these cycles do not have any practical negative consequences on the Rust ecosystem. What cargo does, is use the ordering on B to resolve feature-level dependencies, then translate the chosen elements of B to determine the chosen elements of S - i.e. the crates that need to be downloaded to satisfy feature-level dependencies.

However, naive ways of translating Cargo crates into other package managers may result in the ordering on S being used by the other package manager. This has the following practical negative consequences:

  • the other package manager may not support cyclic dependencies on S

  • even if it supports cyclic dependencies on S in the general case, in a specific case S may contain crates that conflict with each other. This would not be the case if the ordering on B were used directly, as conflicts on this level are self-policed away by Rust developers; but there is no such self-policing on the level of S.

Dependencies