diff --git a/src/crates-and-source-files.md b/src/crates-and-source-files.md index 637f003f8..0fddee91a 100644 --- a/src/crates-and-source-files.md +++ b/src/crates-and-source-files.md @@ -14,7 +14,7 @@ > Note: Although Rust, like any other language, can be implemented by an > interpreter as well as a compiler, the only existing implementation is a -> compiler,and the language has always been designed to be compiled. For these +> compiler, and the language has always been designed to be compiled. For these > reasons, this section assumes a compiler. Rust's semantics obey a *phase distinction* between compile-time and @@ -42,10 +42,10 @@ extension `.rs`. A Rust source file describes a module, the name and location of which — in the module tree of the current crate — are defined from outside the -source file: either by an explicit `mod_item` in a referencing source file, or -by the name of the crate itself. Every source file is a module, but not every -module needs its own source file: [module definitions][module] can be nested -within one file. +source file: either by an explicit [`mod` item][module] in a referencing +source file, or by the name of the crate itself. Every source file is a +module, but not every module needs its own source file: [module +definitions][module] can be nested within one file. Each source file contains a sequence of zero or more `item` definitions, and may optionally begin with any number of [attributes] diff --git a/src/items/modules.md b/src/items/modules.md index 4ffbf47a6..f22b69bff 100644 --- a/src/items/modules.md +++ b/src/items/modules.md @@ -1,6 +1,6 @@ # Modules -> **Syntax:**\ +> **Syntax:**\ > _Module_ :\ >       `mod` [IDENTIFIER] `;`\ >    | `mod` [IDENTIFIER] `{`\ @@ -40,34 +40,88 @@ 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. -A module without a body is loaded from an external file, by default with the -same name as the module, plus the `.rs` extension. When a nested submodule is -loaded from an external file, it is loaded from a subdirectory path that -mirrors the module hierarchy. +## 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 Path | Filesystem Path | File Contents +------------------------- | --------------- | ------------- +`crate` | `lib.rs` | `mod util;` +`crate::util` | `util.rs` | `mod config;` +`crate::util::config` | `util/config.rs` | + +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. + +### `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: ```rust,ignore -// Load the `vec` module from `vec.rs` -mod vec; +#[path = "foo.rs"] +mod c; +``` -mod thread { - // Load the `local_data` module from `thread/local_data.rs` - // or `thread/local_data/mod.rs`. - mod local_data; +Source File | `c`'s File Location | `c`'s Module Path +-------------- | ------------------- | ---------------------- +`src/a/b.rs` | `src/a/foo.rs` | `crate::a::b::c` +`src/a/mod.rs` | `src/a/foo.rs` | `crate::a::c` + +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: + +```rust,ignore +mod inline { + #[path = "other.rs"] + mod inner; } ``` -The directories and files used for loading external file modules can be -influenced with the `path` attribute. +Source File | `inner`'s File Location | `inner`'s Module Path +-------------- | --------------------------| ---------------------------- +`src/a/b.rs` | `src/a/b/inline/other.rs` | `crate::a::b::inline::inner` +`src/a/mod.rs` | `src/a/inline/other.rs` | `crate::a::inline::inner` + +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): ```rust,ignore #[path = "thread_files"] mod thread { - // Load the `local_data` module from `thread_files/tls.rs` + // 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 @@ -94,5 +148,6 @@ The built-in attributes that have meaning on a function are [`cfg`], [IDENTIFIER]: identifiers.html [attribute]: attributes.html [items]: items.html +[module path]: paths.html [prelude]: crates-and-source-files.html#preludes-and-no_std [the lint check attributes]: attributes.html#lint-check-attributes