I am pretty new to Rust and I find the docs can be a little confusing sometimes so I’d be really thankful for people who can help me understand this.
So for my uni project we are doing part of it in Rust. and I am having issues understanding how the modules function. So here is my example program.
Main.rs does some stuff and then passes a pointer into a function from a separate Rust file. That function then does some more things and passes a new variable into a function form another separate Rust file as a pointer.
main.rs has mod separate_file1; and then in separate_file 1 there is a mod separate_file2;.
The confusion is that separate_file2 does not read from the same directory as main.rs despite being in it. Instead it looks in a sub-folder under the same name.
If someone could explain to me why it works like this and what the best practice is for using modules I would be really thankful. It’s made me struggle a lot.


Yeah, it’s tricky that the file for a module is in a subfolder under the file that declared it, unless the file that declared it is named
main.rs,lib.rs, ormod.rsin which cases the module file is in the same folder, not in a subfolder. There is logic to it, but you have to connect multiple rules to get there.We see in the examples above that a module named
whatevercan be inwhatever.rsor inwhatever/mod.rsand you get the same result.mod.rsis a special name with a special lookup rule.whatever/mod.rs whatever/submodule_of_whatever.rsworks exactly the same aswhatever.rs whatever/submodule_of_whatever.rs. We usemod.rsso we don’t have to have both a folder and an.rsfile with the same name. But that leads to the special exception where submodules declared inmod.rsare defined by files in the same folder asmod.rs.main.rsis like themod.rsof the entire crate.main.rshas a special rule where it’s in the same folder as its submodules, instead of the normal rule where submodules are in a subfolder.lib.rsfellows the same special rule asmain.rs. (You usemain.rsto define an executable,lib.rsto define a library.)It is not that tricky if you shift your perspective. Rather than thinking about files importing files (like you would in other languages), think about the crate as a tree of modules. Then the rules are simple.
main.rsandlib.rsare the entry points to the crate and define the root module. Other modules are nested under this and may exist in a file that matches the modules path in the tree. So a module atcrate::foo::bar::bazcan live in eitherfoo/bar/baz.rsorfoo/bar/baz/mod.rs. Or be defined as a inline module in the parent module (which may also be defined inline in its parent).This also means if you know the file path you know where it will exist in the tree,
a/b/c/d.rswill be at the crate patha::b::c::d.Yes, I like your explanations and I agree that’s the way to think about it. But either way you have some special exceptions because
main.rsmaps tocrateinstead of tocrate::main, anda/mod.rsmaps tocrate::ainstead of tocrate::a::mod. I know that’s the same thing you said, but I think it’s worth emphasizing that the very first file you work with is one of the exceptions which makes it harder to see the general rule. It works just the way it should; but I sympathize with anyone getting started who hasn’t internalized the special and general rules yet.