'How come Rust has trouble finding transitive dependencies? [duplicate]

In Rust I'm getting the error during cargo build:

 use tokio::net::{TcpListener, TcpStream};
     ^^^^^ use of undeclared crate or module `tokio`

even though I have

[dependencies]
tokio-tungstenite = {version = "0.17", features = ["native-tls"]}

and I can see the tokio in the cargo tree

└── tokio-tungstenite v0.17.1
    ├── tokio v1.18.1

Is Rust not pulling in the transitive dependencies? I thought it would.



Solution 1:[1]

This is by design. You have to add tokio to your dependencies for it to be available. Under the hood cargo will attempt to re-use the same tokio version, but it is not always possible to do so.

For example lets say your dependencies look like this:

[dependencies]
foo = "0.4.9"  # Depends on sap = "0.2.1"
bar = "1.2.1"  # Depends on sap = "0.9.7"

These two crates depend on different versions of sap. Since cargo is unable to find a version that both crates are happy with, it builds both. At this point it is completely ambiguous which version cargo should supply your crate.

However, you can use * to instead ask cargo to choose a version for you.

sap = "*"

You can read more about how versions are handled here:

https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html

Solution 2:[2]

Cargo does pull transitive dependencies, but it doesn't mean you can access them. You have to explicitly declare that you want it to be a "direct" dependency of your crate for it to be accessible.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 BlackBeans