Basic analysis of the module tree access

I've read some chapters in the Rust book with information about the Module System, Paths, and so on. The material was geared towards beginners.

I don't remember any general comments about which paths in the Module Tree are reachable or not, depending on where we start from. I thought it could be a good-but-simple exercise and topic to create for discussion.

My current general ideas about the access to items in the tree are:

  • Any item would be reachable from anywhere, were all items public.

  • Such item can not access into a parent private module. I mean this kind of access "super::super::other_private_module::pub_member" unless it is a public module.

  • They can though, paralleling the example above, do "super::super::other_pub_module::pub_member"

In other words, they would not be to go up the tree and then take a different branch in the module system, unless the branch is public. But the item can "go up" the tree, and access any non-private-module,

Leaving off minute details for advanced use-cases, are there some corrections or extra considerations I am probably missing, that would be good to know?

Perhaps you prefer the more formal Reference? Particularly:

No that statement "Geared towards beginners" was just so that users calibrate their answers and aren't too advanced.

I will still take a look at the references. Thank you.

I think the exercise came about when thinking where to place test modules. (not done yet, just pondering about it.)

From OP, it must be a child or a sibling of the item to test. But it may be worth placing it in a child module, to test a few extra items together.

So in some sense one must position the test modules somewhat strategically. It could be wrong.

(disregarding integration tests)

If you want to test private items then yes, you must put unit tests into the module or a submodule. Usually you'll see unit tests in a

#[cfg(test)]
mod tests;

module. The book also has a chapter on how to organise your unit and integration tests.

I think there was a mistake in the first post.

Not all public modules are reachable from anywhere, right? (that's the first bullet.)

To use an item in some other module-file it needs to be reachable with mod. But this can add only very specific items.

Example
// main.rs
use crate::additions::add2;

//mod additions; // contains add2

pub fn add(left: u64, right: u64) -> u64 {
    add2(); // assume this is in `additions::add2`
    left + right
}

fn main(){
   add(1,2);
}

The only way to use add2 from additions module is to first use mod additions but that can only find very specific modules.


In summary, when modules are split into files there is an extra constraint for how to "add" those files; but if that's done then the paths are all allowed.

However, there is a pretty strong restriction of what one item can access based on what can be reached with "mod" I would say.

Is this incorrect, and in which ways?

I guess one could still say that all modules are reachable from anywhere but must be "loaded" in the module tree by a mod.

This paragraph makes it clear:

Note that you only need to load a file using a mod declaration once in your module tree. Once the compiler knows the file is part of the project (and knows where in the module tree the code resides because of where you’ve put the mod statement), other files in your project should refer to the loaded file’s code using a path to where it was declared, as covered in the “Paths for Referring to an Item in the Module Tree” section.