There are two similar but slightly different things here, which are almost but not quite the same thing: Cargo targets, and crates. These are both not the same thing as modules.
A crate is an entity in the Rust language; it's the compilation unit of Rust; the thing that rustc
processes exactly one of when it is run. Crates matter in the language for things like the orphan rule and crate::
paths. A crate is defined by a single “crate root” source file, but may include other files the root file references. A crate compilation can produce either a library or binary; if binary, then a fn main()
must be defined in the crate root file.
Cargo targets are essentially declarations of crates; they are often created automatically from the presence of files, but you can also declare them in Cargo.toml
, and they are what you can name on the command line when you are asking Cargo to build something. (Cargo targets are not quite 1:1 with crates, because, for example, “the unit-tests of the binary” are a separate crate from “the binary” and this matters sometimes.)
By default, and in most published Rust code, Cargo’s “target auto-discovery” defines crates based on files. Unfortunately, it's not really rigorously documented; that page and the Package Layout page are the best documentation available. The way I would explain it is: a target (and hence, at least one crate) is automatically defined whenever one of the following filenames is found:
src/lib.rs
src/main.rs
src/bin/*.rs
src/bin/*/main.rs
benches/*.rs
benches/*/main.rs
examples/*.rs
examples/*/main.rs
tests/*.rs
tests/*/main.rs
Every target has a name — it is taken from the part of the path denoted *
in this list, or, for src/lib.rs
and src/main.rs
, defaults to the same name as is declared for the [package]
.
A module is either the crate root itself or item defined in a crate using the mod
keyword. Every source file that is not one of the above crate-root files is brought in to the crate using mod
(or include!
). For more precise information on crates and modules, see Crates and source files.
Much like Cargo target auto-discovery, rustc
has default rules for where module files go, but those operate in the opposite fashion; instead of seeing a file and concluding it should be a module, rustc
infers where to look for source based on the name of your mod
and its containing module.