2

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?

1 Answer 1

3

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 consts, 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!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.