Use of undeclared crate or module `tokio` error caused by adding in a dependency to Cargo.toml

Hey there,

I started running into an issue where all of my tokio::spawn calls within my internal core crate, are getting this error:

lib.rs

error[E0433]: failed to resolve: use of undeclared crate or module `tokio`
  --> /.cargo/registry/src/<artifactory-url>/core-0.4.1-dev.16/src/lib.rs:38:32
   |
38 |                     tasks.push(tokio::spawn(async move {
   |                                ^^^^^ use of undeclared crate or module `tokio`

This worked perfectly fine until adding the following dependencies to my Cargo.toml file. Having either one of these throws the issue above.

config.toml for core

rusoto_dynamodb = {version="=0.47.0", default-features = false, features=["rustls"]}
rusoto_core = {version="=0.47.0", default-features = false, features=["hyper-rustls"]}

The way our project is structured is that we have an AWS lambda service that has our internal core crate as a dependency. we are publishing core to artifactory and pulling it into our project like this:

Cargo.toml for AWS Lambda service

[package]
name = "lambda"
version = "0.1.0"
edition = "2018"
autobins = false

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
tokio = {version = "1", features = ["full"]}
serde = "1.0.126"
serde_derive = "1.0.126"
serde_json = "1.0.64"
log = "^0.4"
simple_logger = {version="^1.16.0", default-features = false, features=["timestamps"]}
lambda_runtime = "0.5.1"
aws_lambda_events = "^0.6.1"
futures = "0.3.17"
mockall = {version="0.10.2"}
mockall_double = "0.2.0"
anyhow = "1.0.52"


core = {version = "=0.4.1-dev.16", registry = "artifactory" } #This is broken


# core = { path = "../../core" } #Commenting this out makes it work. 

[[bin]]
name = "bootstrap"
path = "src/main.rs"

[profile.release]
lto = "thin"

whats very strange is that everything builds fine in the core repository on its own.

Additionally, from within my lambda, if I comment out the local version of the dependency, which has the same exact code as the released version on artifactory, everything seems to build fine when I try building the lambda with the following command

cargo build --release --target x86_64-unknown-linux-musl --verbose

It is only when I try to reference the released version of the core dependency (version 0.4.1-dev.16) that I get this issue with tokio.

For reference, here is the entire Config.toml for the core crate:

[package]
name = "core"
version = "0.4.1"
edition = "2018"
autobins = false
publish = ["artifactory"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
tokio = {version = "1", features = ["full"]}
serde = "1.0.126"
serde_derive = "1.0.126"
serde_json = "1.0.64"
log = "^0.4"
aws_lambda_events = "^0.6.2"
chrono = "0.4.19"
itertools = "0.10.2"
futures = "0.3"
mockall = {version="0.10.2"}
mockall_double = "0.2.0"
lazy_static = "1.4.0"
aws-sdk-sns = "0.0.25-alpha"
anyhow = "1.0.52"
rusoto_dynamodb = {version="=0.47.0", default-features = false, features=["rustls"]}
rusoto_core = {version="=0.47.0", default-features = false, features=["hyper-rustls"]}

Internal A = { version = "2.0.0", registry = "artifactory" }
Internal B = { version = "0.2.0", registry = "artifactory" }
... other internal dependencies

[dev-dependencies]
tokio = { version = "1.0", features = ["macros"] }
async-trait = "0.1.51"
serde_dynamo = "2.4.0"
serial_test = "0.5.1"
http = "0.2.5"
testing_logger = "0.1.1"

This leaves me with two questions:

  1. Why does the lambda service build fine when I reference the local version of core but then when I release that code and reference it from artifactory, it breaks?
  2. What in the rusoto_core or rusoto_dynamodb crates could be causing the issue where tokio is not able to be found?

Any help is greatly appreciated.

here are some links to the crates that are giving me trouble.

My guess is it's because you named your core crate the same as one of the standard library crates. Use another name.

Hi alice,

I obfuscated the internal name of our crate by calling it core. apologies if that brought some confusion.

let's call the crate processor_logic to make more sense. This crate's lib.rs file does have a pub mod named core, though.

pub mod core {
... # logic where issue is happening
}

Why do you have tokio in your dev dependencies as well? You should remove it from there.

1 Like

Is there any chance this code is within an exported macro being called from another crate that has no direct tokio dependency itself?

In such cases the workaround is you have to export something, perhaps the entire tokio crate, then qualify it with $crate::.

This code is not within an exported macro. my AWS Lambda service directly calls the crate with the build issue.

Here is the lambda code for context.

extern crate lambda_runtime as lambda;
extern crate log;
extern crate serde_derive;
extern crate simple_logger;

use lambda_runtime::{service_fn, Error as LambdaError};
use mockall::automock;

#[tokio::main]
async fn main() -> Result<(), LambdaError> {
    let func = service_fn(service::handler);
    lambda_runtime::run(func).await?;
    Ok(())
}

pub mod service {
    use processor_logic::core;
    use lambda_runtime::LambdaEvent;
    use anyhow::Result;
    use aws_lambda_events::event::sqs::SqsEvent;

    pub async fn handler(event: LambdaEvent<SqsEvent>) -> Result<()> {
        let result = core::core_logic(event.payload).await; //crate with the build issue
        return result;
    }
}