Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rust mod files in the same folder vs use

Tags:

rust

I have the following file structure:

  • src
    • function.rs
    • main.rs
    • misc_helpers.rs
    • method.rs

In the main.rs I do the following:

mod misc_helpers;
mod method;
mod function;

because I use functions from these modules. Now in method.rs I use functions from misc_helpers.rs and function.rs. To include these files I want to use mod (just like in main.rs) but it gives me the error:

file not found for module `misc_helpers`
help: to create the module `misc_helpers`, create file "src/method/misc_helpers.rs"

I've found that I have 2 solutions:
(Solution 1) src/method.rs

use super::misc_helpers;
use super::function::*;

(Solution 2) src/method.rs

#[path = "misc_helpers.rs"] mod misc_helpers;
#[path = "function.rs"] mod function;
use function::*;

So I have 3 questions:

  1. Why in the method.rs I can't just mod my way out without using path (like in main.rs)? I guess that main.rs should be considered as a cargo module (i.e. root module) and I can only use mod to include "child" modules (deeper in the module hierarchy) and not "parent" ones?
  2. Why does use super:: work (in method.rs) even though I don't include the files?
  3. What's the better solution (1 or 2) and why?
like image 876
Flone Avatar asked Oct 31 '25 05:10

Flone


1 Answers

Why in the method.rs I can't just mod my way out without using path (like in main.rs)? I guess that main.rs should be considered as a cargo module (i.e. root module) and I can only use mod to include "child" modules (deeper in the module hierarchy) and not "parent" ones?

Because the point of mod is to declare modules. In essence, mod foo; stands for:

mod foo {
    include!("foo.rs");
}

with the modulo that the resolution is a bit more complicated: generally from a module it will look for submodules so from a.rs it will look for a/{name}.rs (or a/{name}/mod.rs), but from a/mod.rs it will look for a/{name}.rs.

The crate root (the root lib.rs or main.rs file) is always in the second case so it'll look for a sibling file, but from that it'll look for a proper submodule.

Why does use super:: work (in method.rs) even though I don't include the files?

Because the point of super is to go up one level in path resolution, and method is a sub-module of the crate root. See the expansion in point 1, same principle.

What's the better solution (1 or 2) and why?

(1) is the actual solution, (2) is not really a solution, it creates duplicated modules through the hierarchy.

That you had to explicitly #[path] the mod in (2) should have hinted at that, it was intentionally introduced to avoid such an unintentional mistake.

An other alternative is to use crate::function::*: where super:: goes up one level to resolve the path, crate:: starts at the crate root.

like image 65
Masklinn Avatar answered Nov 02 '25 03:11

Masklinn