Cargo build shows unresolved import

I've got a project that has a couple rust source files other than main.rs. The other files, say a.rs and b.rs depend on each other.

a.rs

use b;

pub fn(){
//code that depends on b
}

b.rs

use a;

pub fn (){
//code that depends on a
}

main.rs

mod a;
mod b;

fn main(){
//code that  depends on a and b
}

src directory
main.rs
a.rs
b.rs

I get the error "unresolved import" when trying to compile with cargo build, but rustc compiles the application with no problems.
Anyone know what I can do to fix this?

You should use the crate:: prefix when importing from your own project.

// b.rs
use crate::a;

// a.rs
use crate::b;

You may also need to add a pub to the mod declarations.

Note that one common point of confusion is that crate:: is not necessary when the use statement is in the same file as the mod statement, but since this is not the case in your code, you must use crate::, and I generally recommend always using it.

I did what you suggested, and it says, for the example above, 'no a in root'. Why does what I did originally compile with rustc but not with cargo, by the way?

It should certainly work with crate::. If not, you are doing something different than what is in your original post. As for rustc, that depends a lot on what arguments you gave it.

You're right. This is supposed to work. I don't know what's wrong with my code and I can't post it here because there's a lot of it

It is on Github at https://github.com/actuday6418/bob though. The code definitely compiles with "rustc main.rs".

Projects that have both a lib.rs and a main.rs are actually compiled as two seperate crates - one library, and a binary that implicitly depends on that library. Your mod declarations are in main.rs, so they are part of the binary crate, not the library crate.

The fix would be to move your mod declarations to lib.rs. Also, remove the mod lib, as there's no reason to have a mod declaration for the root of a crate.

If you need to access the modules from main.rs, make them pub and then do (for example) use bob::lexical_analysis at the top of main.rs.

EDIT: You also have crate::lib imports in your submodules - these should be removed, and instead of doing (for example) lib::Headers, you should just do crate::Headers.

With these changes, your code compiles (albeit with a lot of warnings, which I'd recommend fixing next):

  • lib.rs
    • Remove use crate::standard_function_declarations.
    • Add pub mod declarations for lexical_analysis and standard_function_declarations.
  • lexical_analysis.rs and standard_function_declarations.rs
    • Remove use crate::lib.
    • Replace all usages of lib with crate.
  • main.rs
    • Remove mod lib.
    • Replace all usages of lib with bob.
    • Replace mod lexical_analysis with use bob::lexical_analysis.
    • Replace mod standard_function_declarations with use bob::standard_function_declarations.
1 Like

Thanks man! That worked, but I don't understand what happened completely. Is there any documentation for this? I didn't see any. Maybe because I stopped reading the book half-way through.

It's covered in chapter 12, but it's not hugely clear about how splitting things into main.rs and lib.rs affects how Cargo compiles the project.

Here's a quick breakdown of how Cargo treats different project layouts:

  • A project with only a lib.rs produces a library that can be depended on by other crates.
    • For example, a project called foo that contains src/lib.rs will produce a library called foo.
  • A project with only a main.rs produces an executable.
    • For example, a project called foo that contains src/main.rs will produce an executable called foo.
  • A library project can optionally create executables as well by placing Rust files in src/bin/.
    • For example, a project called foo that contains src/lib.rs and src/bin/bar.rs will produce a library called foo and an executable called bar.
    • The files in src/bin have an implicit dependency on the library - so bar.rs can do use foo to pull stuff out of the library. The library, on the other hand, knows nothing about the executables.
  • Important bit: Adding a main.rs to a project with a lib.rs is exactly the same as adding a file to src/bin/. It's still a library project, it just has an extra associated executable.
    • For example, in a project called foo, adding a src/main.rs does exactly the same thing as adding a src/bin/foo.rs. In both cases, the project will produce a library called foo, and an executable that's also called foo.

In your case, you were running into issues because your submodules were all declared inside the executable, which as noted above, the library has no knowledge of. You now have the submodules declared in the library, so both the library and the executable are able to access them.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.