aka:Rust
- The Rust Compiler
- Although Rust, like any other language, can be implemented by an interpreter as well as a compiler, the only existing implementation is a compiler — referred to as the Rust compiler — and the language has always been designed to be compiled.
- Crates
- A crate is synonymous with a ‘library’ or ‘package’ in other languages.
- 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.
- 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.
- 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.
- 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 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 that apply to the containing module, most of which influence the behavior of the compiler. The anonymous crate module can have additional attributes that apply to the crate as a whole.
// 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)]
- A crate that contains a main function can be compiled to an executable. If a main function is present, its return type must be unit and it must take no arguments.
- Modules
- 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:
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, or type parameter can't shadow the name of a module in scope, or vice versa.
- 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.
// Load the `vec` module from `vec.rs` mod vec; mod thread { // Load the `local_data` module from `thread/local_data.rs` // or `thread/local_data/mod.rs`. mod local_data; }
- The directories and files used for loading external file modules can be influenced with the path attribute.
- Items and Attributes
- Crates contain items, each of which may have some number of attributes attached to it.
- Items
- An item is a component of a crate. Items are organized within a crate by a nested set of modules. Every crate has a single "outermost" anonymous module; all further items within the crate have paths within the module tree of the crate.
- Items are entirely determined at compile-time, generally remain fixed during execution, and may reside in read-only memory.
- There are several kinds of item:
- extern crate declarations
- use declarations
- modules
- functions
- type definitions
- structures
- enumerations
- constant items
- static items
- traits
- implementations
- Some items form an implicit scope for the declaration of sub-items. In other words, within a function or module, declarations of items can (in many cases) be mixed with the statements, control blocks, and similar artifacts that otherwise compose the item body. The meaning of these scoped items is the same as if the item was declared outside the scope — it is still a static item — except that the item's path name within the module namespace is qualified by the name of the enclosing item, or is private to the enclosing item (in the case of functions). The grammar specifies the exact locations in which sub-item declarations may appear.
- Attributes
- Any item declaration may have an attribute applied to it. Attributes in Rust are modeled on Attributes in ECMA-335, with the syntax coming from ECMA-334 (C#). An attribute is a general, free-form metadatum that is interpreted according to name, convention, and language and compiler version. Attributes may appear as any of: A single identifier, the attribute name An identifier followed by the equals sign '=' and a literal, providing a key/value pair An identifier followed by a parenthesized list of sub-attribute arguments
- Attributes with a bang ("!") after the hash ("#") apply to the item that the attribute is declared within. Attributes that do not have a bang after the hash apply to the item that follows the attribute.
- An example of attributes:
// General metadata applied to the enclosing module or crate. #![crate_type = "lib"] // A function marked as a unit test #[test] fn test_foo() { /* ... */ } // A conditionally-compiled module #[cfg(target_os="linux")] mod bar { /* ... */ } // A lint attribute used to suppress a warning/error #[allow(non_camel_case_types)] type int8_t = i8;
- Types
- Type Parameters
- All items except modules, constants and statics may be parameterized by type. Type parameters are given as a comma-separated list of identifiers enclosed in angle brackets (<...>), after the name of the item and before its definition. There are no general type-parametric types, only type-parametric items. That is, Rust has no notion of type abstraction: there are no higher-ranked (or "forall") types abstracted over other types, though higher-ranked types do exist for lifetimes.
- aka:Rust:Type
- Type Parameters