Test
Test

Reputation: 1720

Cannot find [package] in the crate root

How do you get rust to recognize a module within a crate? I believed it was enough to declare mod [module name] in lib.rs. Is it not?

Error:

error[E0432]: unresolved import `crate::a`
 --> src/bin/b.rs:2:12
  |
2 | use crate::a::f;
  |            ^ could not find `a` in the crate root

src/a.rs:

pub fn f() {}

src/bin/b.rs:

use crate::a::f;

fn main() {}

src/lib.rs:

mod a;

Cargo.toml:

[package]
name = "m"
version = "0.1.0"
edition = "2021"

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

[[bin]]
name = "b"
path = "src/bin/b.rs"

[dependencies]

Upvotes: 2

Views: 14042

Answers (2)

Niklas Mohrin
Niklas Mohrin

Reputation: 1928

You are confusing crates and packages. As per the corresponding chapter in the book:

A crate is the smallest amount of code that the Rust compiler considers at a time. [...] A crate can come in one of two forms: a binary crate or a library crate.

This means that your lib.rs and bin/b.rs files define two separate crates and thus crate refers to different things. Both belong to the same package which is defined by your Cargo.toml file. To use functions from your library crate in your binary crate, use the crate name instead of crate. In your case, the crate name is the same as the package name, which is m. Note that you will have to mark your library items as pub to use them in another crate.

An example of this can be found in the bat program, which uses both crate and bat in the imports of the bat binary crate:

Upvotes: 4

Locke
Locke

Reputation: 8982

When a binary is compiled it is seen as the root of the project structure. So lib.rs is not compiled for binary targets and you can not use any of its modules unless you also add them in your binary. The most common approach is to put your binaries in the src folder with lib.rs so you don't need to worry about the folder structure when using your modules. I suppose you could use include!("lib.rs"); at the top of your binary to make it inherit everything from your library, but I have not tried it and it would likely be considered bad form.

However, you can sidestep the issue by making your binary depend on your library. The easiest way to do this is by making your binary its own crate which depends on your library.

There are also some ways to get around this, is by making a crate a dependency of itself, but these solutions always make me feel a little uneasy about the stability of the solution. This answer can give you a general idea of what that looks like.

Here are some examples various solutions. In case you are wondering, these are just the first crates I found that fit the design pattern. I do not know what some of them do/contain.

Upvotes: 1

Related Questions