cargo icon indicating copy to clipboard operation
cargo copied to clipboard

cargo shows that `tokio` with the `default` feature depends on `mio`, which is incorrect.

Open themighty1 opened this issue 1 year ago • 5 comments

When running cargo tree on my project, mio is shown as a dependency of tokio with the default feature, which is incorrect, since mio is tokio's optional dependendy only for features net, process, signal (as per https://github.com/tokio-rs/tokio/blob/master/tokio/Cargo.toml)

To reproduce: (EDITED to reflect the recent dir reorg)

git clone https://github.com/tlsnotary/tlsn
cd tlsn
git checkout 68b9474015b817255c226fec38e80addd16191d1
cd components/tls/tls-mpc/
cargo tree -e normal,dev,features | grep mio -B10

you will see this Screenshot from 2024-07-18 09-12-57

themighty1 avatar Jul 18 '24 06:07 themighty1

I think the default here refers to the default of package(tlsn-utils-aio) that enables tokio.

eth3lbert avatar Jul 21 '24 06:07 eth3lbert

@eth3lbert , are you suggesting that tokio feature "default" means something else other than the default feature of the tokio crate? I don't think that's how cargo tree works. It only shows the enabled features of this dependency, i.e. of the dependency mentioned on the same line as the feature.

Or amiwrong?

themighty1 avatar Jul 22 '24 05:07 themighty1

You could try using inverse mode with cargo tree -e features -p mio -i. This might make more sense to you.

eth3lbert avatar Jul 22 '24 06:07 eth3lbert

@eth3lbert There is something definitely wrong in the tree output. For example, the "tokio feature "net" edge is completely missing. All optional dependencies should have a feature edge to them to explain why they are enabled. I don't know what is going wrong, it will take some investigation why the feature edges are missing.

ehuss avatar Jul 22 '24 12:07 ehuss

@rustbot claim

I will take a look.

0xPoe avatar Aug 07 '24 14:08 0xPoe

To simplify the example:

cargo new cargo-tree-test
cd cargo-tree-test
cargo add [email protected] --features net
cargo tree -e features

shows:

cargo-tree-test v0.1.0
├── tokio feature "default"
│   └── tokio v1.43.0
│       ├── mio v1.0.3
│       │   └── libc feature "default"
│       │       ├── libc v0.2.169
│       │       └── libc feature "std"
│       │           └── libc v0.2.169
│       ├── libc feature "default" (*)
│       ├── pin-project-lite feature "default"
│       │   └── pin-project-lite v0.2.16
│       ├── socket2 feature "all"
│       │   └── socket2 v0.5.8
│       │       └── libc feature "default" (*)
│       └── socket2 feature "default"
│           └── socket2 v0.5.8 (*)
└── tokio feature "net"
    ├── tokio v1.43.0 (*)
    ├── tokio feature "libc"
    │   └── tokio v1.43.0 (*)
    ├── tokio feature "mio"
    │   └── tokio v1.43.0 (*)
    ├── tokio feature "socket2"
    │   └── tokio v1.43.0 (*)
    ├── mio feature "net"
    │   └── mio v1.0.3 (*)
    ├── mio feature "os-ext"
    │   ├── mio v1.0.3 (*)
    │   └── mio feature "os-poll"
    │       └── mio v1.0.3 (*)
    └── mio feature "os-poll" (*)

There is a tokio feature "net" leading to a tokio feature "mio" but no explicit depiction on how this connects to the mio dependency.

What is the intended output in this example? Is there any documentation on how this should behave?

Imberflur avatar Feb 01 '25 06:02 Imberflur

That output looks correct: tokio's "net" feature explicitly enables several mio features and thus also enables the optional mio dependencies.

Regarding the issue as it was originally reported, I don't think there is any bug:

  • Tokio with only default features enabled does not depend on mio, as expected.
  • The project linked by @themighty1 enables tokio's "net" feature (among others), that's why mio is pulled in. Indeed the edge from tokio feature "net" to mio feature "{os-poll,os-ext,net}" occurs in the cargo tree output, just not in the screenshot that was shared. I also see lots of edges towards tokio feature "net" explaining why it gets enabled.
  • The part of the output that's shown in the screenshot is technically correct, just somewhat confusing. The tokio feature "default" is enabled by a bunch of crates in the dependency graph, this feature obviously has an edge to the tokio crate, and then cargo tree prints the things that tokio in general depends on because "normal" (non-feature) edges are also requested. Due to feature unification, there only a single version of tokio, no separate "tokio with only default feature vs. tokio with only net feature".

hanna-kruppe avatar Feb 01 '25 09:02 hanna-kruppe

because "normal" (non-feature) edges are also requested

I'm not sure if this is accurate since my example has similar output without -e normal. I think including normal just disables the default of also showing build dependencies and dev dependencies.

Imberflur avatar Feb 01 '25 14:02 Imberflur

Yeah, my phrasing was sloppy. What I was trying to get at is, if normal dependency edges weren't included, you wouldn't see much of anything in the output (try cargo tree -e features,no-normal in your example). At least one of normal/dev/build dependency edges have to be considered together with the feature edges to get the transitive closure of enabled features in your build.

hanna-kruppe avatar Feb 01 '25 14:02 hanna-kruppe

I'm also facing some similar issues when showing dependency tree for target wasm32-unknown-unknown

git clone https://github.com/nervosnetwork/ckb-sdk-rust
cd ckb-sdk-rust
echo 1.85.0 > rust-toolchain
cargo tree -p mio -i -e features,no-dev --target wasm32-unknown-unknown

The output shows that mio was included in the dependency graph without any tokio features like net:

mio v1.0.3
└── tokio v1.44.2
    ├── tokio feature "default"
    │   ├── ckb-script v0.200.0
    │   │   ├── ckb-script feature "ckb-logger"
    │   │   │   └── ckb-script feature "logging"
    │   │   │       └── ckb-script feature "default"
    │   │   │           └── ckb-sdk v3.7.0 (/root/test3/ckb-sdk-rust)
    │   │   │               ├── ckb-sdk feature "default" (command-line)
    │   │   │               └── ckb-sdk feature "default-tls"
    │   │   │                   └── ckb-sdk feature "default" (command-line)
    │   │   ├── ckb-script feature "default" (*)
    │   │   ├── ckb-script feature "detect-asm"
    │   │   │   └── ckb-script feature "default" (*)
    │   │   └── ckb-script feature "logging" (*)
    │   ├── ckb-sdk v3.7.0 (/root/test3/ckb-sdk-rust) (*)
    │   └── tokio-util v0.7.15
    │       ├── tokio-util feature "codec"
    │       │   └── ckb-sdk v3.7.0 (/root/test3/ckb-sdk-rust) (*)
    │       └── tokio-util feature "default"
    │           └── ckb-sdk v3.7.0 (/root/test3/ckb-sdk-rust) (*)
    ├── tokio feature "macros"
    │   └── ckb-script v0.200.0 (*)
    ├── tokio feature "sync"
    │   ├── ckb-script v0.200.0 (*)
    │   └── tokio-util v0.7.15 (*)
    └── tokio feature "tokio-macros"
        └── tokio feature "macros" (*)

Officeyutong avatar Apr 28 '25 09:04 Officeyutong