I think myself that the biggest issue with Rust’s module system is language not helpful enough if you get it wrong unlike other parts of a language, which is very likely if you are learning Rust.
When making a new project in Rust, a following tree is created.
|-- Cargo.tml
`-- src
`-- lib.rs
src
is encouraging in saying to an user - hey, put more stuff here - this is a good design here as it makes it clear that you can put more files - too bad that rest of the compiler doesn’t work together with it. So they can say decide to make a file called another_file.rs
, and even put some content here.
fn method() -> i32 {
42
}
Everything compiles successfully, no warnings, now how to use that from lib.rs
?
pub fn external_number() {
another_file::method();
}
Now to compile this.
error[E0433]: failed to resolve. Use of undeclared type or module `another_file`
--> src/lib.rs:2:5
|
2 | another_file::method();
| ^^^^^^^^^^^^^^^^^^^^ Use of undeclared type or module `another_file`
error: aborting due to previous error
error: Could not compile `example-crate`.
To learn more, run the command again with --verbose.
--verbose
info is useless for this issue by the way. No hints about what needs to be done. Uh, mentioning crate name will fix it? Surely, right?
pub fn external_number() {
example_crate::another_file::method();
}
error[E0433]: failed to resolve. Use of undeclared type or module `example_crate`
--> src/lib.rs:2:5
|
2 | example_crate::another_file::method();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use of undeclared type or module `example_crate`
So perhaps it should be used, I mean, that’s how it works in Perl and other programming languages. You need to import something before using it. There is use
keyword, it’s surely for that, I mean, it’s very similar to something like use std::collections::HashMap
so it has to be it. Also documentation for E0433
suggests using use
keyword.
use another_file;
pub fn external_number() {
another_file::method();
}
error[E0432]: unresolved import `another_file`
--> src/lib.rs:1:5
|
1 | use another_file;
| ^^^^^^^^^^^^ no `another_file` in the root
Perhaps name of crate needs to be mentioned?
use example_crate::another_file;
pub fn external_number() {
another_file::method();
}
error[E0432]: unresolved import `example_crate::another_file`
--> src/lib.rs:1:5
|
1 | use example_crate::another_file;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Maybe a missing `extern crate example_crate;`?
Alright compiler, let’s put extern crate
if that’s the issue.
extern crate example_crate;
use example_crate::another_file;
pub fn external_number() {
another_file::method();
}
error[E0463]: can't find crate for `example_crate`
--> src/lib.rs:1:1
|
1 | extern crate example_crate;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
But that crate is like… right here, what’s wrong with you compiler.
Okay, I’m done here, four unsucessful attempts to do something, and one misleading hint from a compiler. Like this surely can be done better, right?
My suggestion is simply to change error message so that when trying to do any of those unsuccessful attempts when there is a directory or a file with requested module name, it should instead hint to use mod
keyword. Something like this possibly.
error[E0433]: failed to resolve. Use of undeclared type or module `another_file`
--> src/lib.rs:2:5
|
2 | another_file::method();
| ^^^^^^^^^^^^^^^^^^^^ Use of undeclared type or module `another_file`
= help: modules need to be declared first
= note: use `mod another_file` to do so
(the error message obviously should be better, I’m not good at English myself)