Skip to content

Extended the module tutorial section about files a bit #9398

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 23, 2013
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 50 additions & 13 deletions doc/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -2420,7 +2420,8 @@ However, in practice you usually want to split you code up into multiple source
In order to do that, Rust allows you to move the body of any module into it's own source file, which works like this:

If you declare a module without its body, like `mod foo;`, the compiler will look for the
files `foo.rs` and `foo/mod.rs`. If it finds either, it uses the content of that file as the body of the module.
files `foo.rs` and `foo/mod.rs` inside some directory (usually the same as of the source file containing
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Usually"? When does it not look in the same directory?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's explained further below that section. It will look for those two relative paths in a directory that is the the path of the source file that contains the mod ...;, concatenated with a path build by concatenating all nested mod ... { ... } statrments the mod ...; is contained in.

// src/foo/bar.rs
mod a {
    mod b {
        mod c; // will look for src/foo/a/b/c.rs and src/foo/a/b/c/mod..rs
    }
}

the `mod foo;`). If it finds either, it uses the content of that file as the body of the module.
If it finds both, that's a compile error.

So, if we want to move the content of `mod farm` into it's own file, it would look like this:
Expand All @@ -2446,7 +2447,7 @@ pub mod barn {
# fn main() { }
~~~~

So, in short `mod foo;` is just syntactic sugar for `mod foo { /* include content of foo.rs or foo/mod.rs here */ }`.
In short, `mod foo;` is just syntactic sugar for `mod foo { /* content of <...>/foo.rs or <...>/foo/mod.rs */ }`.

This also means that having two or more identical `mod foo;` somewhere
in your crate hierarchy is generally a bad idea,
Expand All @@ -2455,14 +2456,14 @@ Both will result in duplicate and mutually incompatible definitions.

The directory the compiler looks in for those two files is determined by starting with
the same directory as the source file that contains the `mod foo;` declaration, and concatenating to that a
path equivalent to the relative path of all nested `mod { ... }` declarations the `mod foo;` is contained in, if any.
path equivalent to the relative path of all nested `mod { ... }` declarations the `mod foo;`
is contained in, if any.

For example, given a file with this module body:

~~~ {.ignore}
// src/main.rs
mod plants;
mod fungi;
mod animals {
mod fish;
mod mammals {
Expand All @@ -2477,25 +2478,61 @@ The compiler would then try all these files:
src/plants.rs
src/plants/mod.rs

src/fungi.rs
src/fungi/mod.rs

src/animals/fish.rs
src/animals/fish/mod.rs

src/animals/mammals/humans.rs
src/animals/mammals/humans/mod.rs
~~~

These rules per default result in any directory structure mirroring
the crates's module hierarchy, and allow you to have both small modules that only need
to consist of one source file, and big modules that group the source files of submodules together.
Keep in mind that identical module hierachies can still lead to different path lookups
depending on how and where you've moved a module body to its own file.
For example, if we move the `animals` module above into its own file...

~~~ {.ignore}
// src/main.rs
mod plants;
mod animals;
~~~
~~~ {.ignore}
// src/animals.rs or src/animals/mod.rs
mod fish;
mod mammals {
mod humans;
}
~~~
...then the source files of `mod animals`'s submodules can
either be placed right next to that of its parents, or in a subdirectory if `animals` source file is:

~~~ {.notrust}
src/plants.rs
src/plants/mod.rs

src/animals.rs - if file sits next to that of parent module's:
src/fish.rs
src/fish/mod.rs

src/mammals/humans.rs
src/mammals/humans/mod.rs

src/animals/mod.rs - if file is in it's own subdirectory:
src/animals/fish.rs
src/animals/fish/mod.rs

src/animals/mammals/humans.rs
src/animals/mammals/humans/mod.rs

~~~

These rules allow you to have both small modules that only need
to consist of one source file each and can be conveniently placed right next to each other,
and big complicated modules that group the source files of submodules in subdirectories.

If you need to circumvent those defaults, you can also overwrite the path a `mod foo;` would take:
If you need to circumvent the defaults, you can also overwrite the path a `mod foo;` would take:

~~~ {.ignore}
#[path="../../area51/classified.rs"]
mod alien;
#[path="../../area51/alien.rs"]
mod classified;
~~~

## Importing names into the local scope
Expand Down