I have the following code:
pub mod a {
#[test]
pub fn test() {
println!("{:?}", std::fs::remove_file("Somefilehere"));
}
}
I get errors when I compile this:
error[E0433]: failed to resolve. Use of undeclared type or module `std`
--> src/main.rs:4:24
|
4 | println!("{}", std::fs::remove_file("Somefilehere"));
| ^^^ Use of undeclared type or module `std`
However, removing the inner module and compiling the code it contains by itself works fine:
#[test]
pub fn test() {
println!("{:?}", std::fs::remove_file("Somefilehere"));
}
What am I missing here? I get the same errors if the module is in a separate file:
main.rs
pub mod a;
a.rs
#[test]
pub fn test() {
println!("{:?}", std::fs::remove_file("Somefilehere"));
}
By default, the compiler inserts
extern crate std;
at the beginning of the crate root (the crate root is the file that you pass torustc
). This statement has the effect of adding the namestd
to the crate's root namespace and associating it with a module that contains the public contents of thestd
crate.However, in child modules,
std
is not automatically added in the module's namespace. This is why the compiler cannot resolvestd
(or anything that starts withstd::
) in a module.There are many ways to fix this. First, you can add
use std;
in a module to make the namestd
refer, within that module, to the rootstd
. Note that inuse
statements, the path is treated as absolute (or "relative to the crate's root namespace"), whereas everywhere else, paths are treated as relative to the current namespace (be it a module, a function, etc.).You can also use a
use
statement to import more specific items. For example, you can writeuse std::fs::remove_file;
. This lets you avoid having to type the whole path toremove_file
and just use the nameremove_file
directly within that module:Finally, you can avoid using
use
altogether by prefixing the path with::
to ask the compiler to resolve the path from the crate's root namespace (i.e. turning the path into an absolute path).The recommended practice is to import types (structs, enums, etc.) directly (e.g.
use std::rc::Rc;
, then use the pathRc
), but to use functions through an import of their parent module (e.g.use std::io::fs;
, then use the pathfs::remove_file
).Side note: You can also write
self::
at the beginning of a path to make it relative to the current module. This is more often used inuse
statements, since other paths are already relative (though they are relative to the current namespace, whereasself::
is always relative to the containing module).