Reputation: 23
I have a small program that I've been trying to get working, but I keep getting unresolved import messages.
main.rs:
mod sub_module;
use sub_module::a_structure;
fn main() {
let x: a_structure = /* init code */;
}
sub_module.rs:
pub mod sub_sub_module;
pub use sub_sub_module::a_structure;
sub_sub_module.rs:
pub struct a_structure<T> {
some_field: i32,
}
However, on executing cargo build
I get an "unresolved import sub_sub_module::a_structure
". Everything I've found regarding visibility says that this should work however it doesn't. What am I missing here?
Upvotes: 2
Views: 1908
Reputation: 59145
Think of Rust modules as being like a directory tree. Modules are directories, everything else is a file [1]. ::
is basically /
.
So, you have this structure:
/ (crate root)
└┬─ sub_module
│ └┬─ sub_sub_module
│ │ └── a_structure
│ └─ a_structure [x]
├─ a_structure
└─ main
The problem is in how you define the a_structure [x]
"symlink". As explained in the book, use
paths in Rust are absolute, meaning in this analogy that they all implicitly start with /
. Meaning that use sub_sub_module::a_structure
is referring to /sub_sub_module/a_structure
, which doesn't exist.
The solution is to use a relative path by explicitly starting the path with self
(effectively .
) or super
(effectively ..
). You want ./sub_sub_module/a_structure
, so the path in Rust should be self::sub_sub_module::a_structure
. A full, compiling (with warnings) example looks like:
mod sub_module {
pub mod sub_sub_module {
pub struct a_structure {
some_field: i32,
}
}
pub use self::sub_sub_module::a_structure;
}
use sub_module::a_structure;
fn main() {
let x: a_structure = panic!("TODO");
}
You should also note that paths used anywhere outside of a use
have the exact opposite default: they are relative to the containing module by default. If you want an absolute path in that case, you need to explicitly ask for one by starting the path with ::
(just like a filesystem path that is, by default, interpreted as relative).
Aside: The conventional style is to use PascalCase
for type names. Also, I had to remove the type parameter because it wasn't being used.
[1]: This is, in fact, a lie, as you can have items associated with other items. For example, associated const
s, while unstable, are a thing. I suppose you could think of them in terms of resource forks or something, I don't know; it's just a metaphor!
Upvotes: 3