commit - f8e76ee9368f498f7f044c719de68c7d95da9972 - 2019-11-08

Module :
      mod IDENTIFIER ;
   | mod IDENTIFIER {

A module is a container for zero or more items.

A module item is a module, surrounded in braces, named, and prefixed with the keyword mod. A module item introduces a new, named module into the tree of modules making up a crate. Modules can nest arbitrarily.

An example of a module:

fn main() {
mod math {
    type Complex = (f64, f64);
    fn sin(f: f64) -> f64 {
        /* ... */
    fn cos(f: f64) -> f64 {
        /* ... */
    fn tan(f: f64) -> f64 {
        /* ... */

Modules and types share the same namespace. Declaring a named type with the same name as a module in scope is forbidden: that is, a type definition, trait, struct, enumeration, union, type parameter or crate can’t shadow the name of a module in scope, or vice versa. Items brought into scope with use also have this restriction.

Module Source Filenames

A module without a body is loaded from an external file. When the module does not have a path attribute, the path to the file mirrors the logical module path. Ancestor module path components are directories, and the module’s contents are in a file with the name of the module plus the .rs extension. For example, the following module structure can have this corresponding filesystem structure:

Module PathFilesystem PathFile Contents
cratelib.rsmod util;
crate::utilutil.rsmod config;

Module filenames may also be the name of the module as a directory with the contents in a file named mod.rs within that directory. The above example can alternately be expressed with crate::util‘s contents in a file named util/mod.rs. It is not allowed to have both util.rs and util/mod.rs.

Note: Previous to rustc 1.30, using mod.rs files was the way to load a module with nested children. It is encouraged to use the new naming convention as it is more consistent, and avoids having many files named mod.rs within a project.

The path attribute

The directories and files used for loading external file modules can be influenced with the path attribute.

For path attributes on modules not inside inline module blocks, the file path is relative to the directory the source file is located. For example, the following code snippet would use the paths shown based on where it is located:

#[path = "foo.rs"]
mod c;
Source Filec‘s File Locationc‘s Module Path

For path attributes inside inline module blocks, the relative location of the file path depends on the kind of source file the path attribute is located in. “mod-rs” source files are root modules (such as lib.rs or main.rs) and modules with files named mod.rs. “non-mod-rs” source files are all other module files. Paths for path attributes inside inline module blocks in a mod-rs file are relative to the directory of the mod-rs file including the inline module components as directories. For non-mod-rs files, it is the same except the path starts with a directory with the name of the non-mod-rs module. For example, the following code snippet would use the paths shown based on where it is located:

mod inline {
    #[path = "other.rs"]
    mod inner;
Source Fileinner‘s File Locationinner‘s Module Path

An example of combining the above rules of path attributes on inline modules and nested modules within (applies to both mod-rs and non-mod-rs files):

#[path = "thread_files"]
mod thread {
    // Load the `local_data` module from `thread_files/tls.rs` relative to
    // this source file's directory.
    #[path = "tls.rs"]
    mod local_data;

Prelude Items

Modules implicitly have some names in scope. These name are to built-in types, macros imported with #[macro_use] on an extern crate, and by the crate’s prelude. These names are all made of a single identifier. These names are not part of the module, so for example, any name name, self::name is not a valid path. The names added by the prelude can be removed by placing the no_implicit_prelude attribute onto the module or one of its ancestor modules.

Attributes on Modules

Modules, like all items, accept outer attributes. They also accept inner attributes: either after { for a module with a body, or at the beginning of the source file, after the optional BOM and shebang.

The built-in attributes that have meaning on a module are cfg, deprecated, doc, the lint check attributes, path, and no_implicit_prelude. Modules also accept macro attributes.