blob: c1f7d3dc6ab59c8ce1d6830ee5167770080e3c34 [file] [log] [blame] [view]
r[crate]
# Crates and source files
r[crate.syntax]
```grammar,items
@root Crate ->
InnerAttribute*
Item*
```
> [!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 reasons, this section assumes a compiler.
r[crate.compile-time]
Rust's semantics obey a *phase distinction* between compile-time and
run-time.[^phase-distinction] Semantic rules that have a *static
interpretation* govern the success or failure of compilation, while
semantic rules that have a *dynamic interpretation* govern the behavior of the
program at run-time.
r[crate.unit]
The compilation model centers on artifacts called _crates_. Each compilation
processes a single crate in source form, and if successful, produces a single
crate in binary form: either an executable or some sort of
library.[^cratesourcefile]
r[crate.module]
A _crate_ is a unit of compilation and linking, as well as versioning,
distribution, and runtime loading. A crate contains a _tree_ of nested
[module] scopes. The top level of this tree is a module that is
anonymous (from the point of view of paths within the module) and any item
within a crate has a canonical [module path] denoting its location
within the crate's module tree.
r[crate.input-source]
The Rust compiler is always invoked with a single source file as input, and
always produces a single output crate. The processing of that source file may
result in other source files being loaded as modules. Source files have the
extension `.rs`.
r[crate.module-def]
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 [Module][grammar-Module] item in a referencing
source file, or by the name of the crate itself.
r[crate.inline-module]
Every source file is a
module, but not every module needs its own source file: [module
definitions][module] can be nested within one file.
r[crate.items]
Each source file contains a sequence of zero or more [Item] definitions, and
may optionally begin with any number of [attributes]
that apply to the containing module, most of which influence the behavior of
the compiler.
r[crate.attributes]
The anonymous crate module can have additional attributes that
apply to the crate as a whole.
> [!NOTE]
> The file's contents may be preceded by a [shebang].
```rust
// Specify the crate name.
#![crate_name = "projx"]
// Specify the type of output artifact.
#![crate_type = "lib"]
// Turn on a warning.
// This can be done in any module, not just the anonymous crate module.
#![warn(non_camel_case_types)]
```
r[crate.main]
## Main Functions
r[crate.main.general]
A crate that contains a `main` [function] can be compiled to an executable.
r[crate.main.restriction]
If a `main` function is present, it must take no arguments, must not declare any
[trait or lifetime bounds], must not have any [where clauses], and its return
type must implement the [`Termination`] trait.
```rust
fn main() {}
```
```rust
fn main() -> ! {
std::process::exit(0);
}
```
```rust
fn main() -> impl std::process::Termination {
std::process::ExitCode::SUCCESS
}
```
r[crate.main.import]
The `main` function may be an import, e.g. from an external crate or from the current one.
```rust
mod foo {
pub fn bar() {
println!("Hello, world!");
}
}
use foo::bar as main;
```
> [!NOTE]
> Types with implementations of [`Termination`] in the standard library include:
>
> * `()`
> * [`!`]
> * [`Infallible`]
> * [`ExitCode`]
> * `Result<T, E> where T: Termination, E: Debug`
<!-- If the previous section needs updating (from "must take no arguments"
onwards, also update it in the testing.md file -->
r[crate.uncaught-foreign-unwinding]
### Uncaught foreign unwinding
When a "foreign" unwind (e.g. an exception thrown from C++ code, or a `panic!` in Rust code using a different panic handler) propagates beyond the `main` function, the process will be safely terminated. This may take the form of an abort, in which case it is not guaranteed that any `Drop` calls will be executed, and the error output may be less informative than if the runtime had been terminated by a "native" Rust `panic`.
For more information, see the [panic documentation][panic-docs].
r[crate.no_main]
### The `no_main` attribute
The *`no_main` [attribute]* may be applied at the crate level to disable emitting the `main` symbol for an executable binary. This is useful when some other object being linked to defines `main`.
r[crate.crate_name]
## The `crate_name` attribute
r[crate.crate_name.general]
The *`crate_name` [attribute]* may be applied at the crate level to specify the
name of the crate with the [MetaNameValueStr] syntax.
```rust
#![crate_name = "mycrate"]
```
r[crate.crate_name.restriction]
The crate name must not be empty, and must only contain [Unicode alphanumeric]
or `_` (U+005F) characters.
[^phase-distinction]: This distinction would also exist in an interpreter.
Static checks like syntactic analysis, type checking, and lints should
happen before the program is executed regardless of when it is executed.
[^cratesourcefile]: A crate is somewhat analogous to an *assembly* in the
ECMA-335 CLI model, a *library* in the SML/NJ Compilation Manager, a *unit*
in the Owens and Flatt module system, or a *configuration* in Mesa.
[Unicode alphanumeric]: char::is_alphanumeric
[`!`]: types/never.md
[`ExitCode`]: std::process::ExitCode
[`Infallible`]: std::convert::Infallible
[`Termination`]: std::process::Termination
[attribute]: attributes.md
[attributes]: attributes.md
[function]: items/functions.md
[module]: items/modules.md
[module path]: paths.md
[panic-docs]: panic.md#unwinding-across-ffi-boundaries
[shebang]: input-format.md#shebang-removal
[trait or lifetime bounds]: trait-bounds.md
[where clauses]: items/generics.md#where-clauses
<script>
(function() {
var fragments = {
"#preludes-and-no_std": "names/preludes.html",
};
var target = fragments[window.location.hash];
if (target) {
var url = window.location.toString();
var base = url.substring(0, url.lastIndexOf('/'));
window.location.replace(base + "/" + target);
}
})();
</script>