From 759eb4584595592d7e4021a2daf589f2b286bb2c Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 14 Dec 2012 19:12:51 -0800 Subject: [PATCH] Update docs for crate file changes --- doc/rust.md | 120 ++++++++++++++++++++---------------------------- doc/tutorial.md | 58 +++++++++++------------ 2 files changed, 78 insertions(+), 100 deletions(-) diff --git a/doc/rust.md b/doc/rust.md index 98d3643704a1f..c57440382031c 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -570,53 +570,31 @@ Semantic rules called "dynamic semantics" govern the behavior of programs at run A program that fails to compile due to violation of a compile-time rule has no defined dynamic semantics; the compiler should halt with an error report, and produce no executable artifact. The compilation model centres 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 a library. +Each compilation processes a single crate in source form, and if successful, produces a single crate in binary form: either an executable or a library.^[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.] 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](#modules) 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](#paths) denoting its location within the crate's module tree. -Crates are provided to the Rust compiler through two kinds of file: - - - _crate files_, that end in `.rc` and each define a `crate`. - - _source files_, that end in `.rs` and each define a `module`. - -> **Note:** The functionality of crate files will be merged into source files in future versions of Rust. -> The separate processing of crate files, both their grammar and file extension, will be removed. - -The Rust compiler is always invoked with a single crate file as input, and always produces a single output crate. - -When the Rust compiler is invoked with a crate file, it reads the _explicit_ -definition of the crate it's compiling from that file, and populates the -crate with modules derived from all the source files referenced by the -crate, reading and processing all the referenced modules at once. - -When the Rust compiler is invoked with a source file, it creates an _implicit_ crate and treats the source file as if it is the sole module populating this explicit crate. -The module name is derived from the source file name, with the `.rs` extension removed. - -## Crate files - -~~~~~~~~ {.ebnf .gram} -crate : attribute [ ';' | attribute* directive ] - | directive ; -directive : view_item | dir_directive | source_directive ; -~~~~~~~~ +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 typically have the extension `.rs` but, by convention, +source files that represent crates have the extension `.rc`, called *crate files*. -A crate file contains a crate definition, for which the production above -defines the grammar. It is a declarative grammar that guides the compiler in -assembling a crate from component source files.^[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.] A crate file describes: +Each source file contains a `module`: that is, a sequence of zero or more +`item` definitions. Each source file is an implicit module, the name and +location of which -- in the module tree of the current crate -- is defined +from outside the source file: either by an explicit `source_directive` in +a referencing crate file, or by the filename of the source file itself. -* [Attributes](#attributes) about the crate, such as author, name, version, - and copyright. These are used for linking, versioning and distributing - crates. -* The source-file and directory modules that make up the crate. -* Any `use` or `extern mod` [view items](#view-items) that apply to - the anonymous module at the top-level of the crate's module tree. +A source file that contains a `main` function can be compiled to an executable. +If a `main` function is present, its return type must be [`unit`](#primitive-types) and it must take no arguments. -An example of a crate file: +Attributes on the anonymous crate module are used to define important metadata that influences +the behavior of the compiler. ~~~~~~~~{.xfail-test} // Linkage attributes @@ -629,40 +607,13 @@ An example of a crate file: license = "BSD" ]; author = "Jane Doe" ]; -// Import a module. -extern mod std (ver = "1.0"); +// Specify the output type +#[ crate_type = "lib" ]; -// Define some modules. -#[path = "foo.rs"] -mod foo; -mod bar { - #[path = "quux.rs"] - mod quux; -} +// Turn on a warning +#[ warn(non_camel_case_types) ]; ~~~~~~~~ -### Dir directives - -A `dir_directive` forms a module in the module tree making up the crate, as -well as implicitly relating that module to a directory in the filesystem -containing source files and/or further subdirectories. The filesystem -directory associated with a `dir_directive` module can either be explicit, -or if omitted, is implicitly the same name as the module. - -A `source_directive` references a source file, either explicitly or implicitly, by combining the module name with the file extension `.rs`. -The module contained in that source file is bound to the module path formed by the `dir_directive` modules containing the `source_directive`. - -## Source files - -A source file contains a `module`: that is, a sequence of zero or more -`item` definitions. Each source file is an implicit module, the name and -location of which -- in the module tree of the current crate -- is defined -from outside the source file: either by an explicit `source_directive` in -a referencing crate file, or by the filename of the source file itself. - -A source file that contains a `main` function can be compiled to an executable. -If a `main` function is present, its return type must be [`unit`](#primitive-types) and it must take no arguments. - # Items and attributes Crates contain [items](#items), @@ -719,7 +670,7 @@ That is, Rust has no notion of type abstraction: there are no first-class "foral ### Modules ~~~~~~~~ {.ebnf .gram} -mod_item : "mod" ident '{' mod '}' ; +mod_item : "mod" ident ( ';' | '{' mod '}' ); mod : [ view_item | item ] * ; ~~~~~~~~ @@ -757,6 +708,33 @@ Declaring a named type that has 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 heirarchy. + +~~~ +// Load the `vec` module from `vec.rs` +mod vec; + +mod task { + // Load the `local_data` module from `task/local_data.rs` + mod local_data; +} +~~~ + +The directories and files used for loading external file modules can be influenced +with the `path` attribute. + +~~~ +#[path = "task_files"] +mod task { + // Load the `local_data` module from `task_files/tls.rs` + #[path = "tls.rs"] + mod local_data; +} +~~~ + #### View items ~~~~~~~~ {.ebnf .gram} diff --git a/doc/tutorial.md b/doc/tutorial.md index 4b443b0da4daa..dd5b1bfb89ef4 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -2252,22 +2252,46 @@ The unit of independent compilation in Rust is the crate: rustc compiles a single crate at a time, from which it produces either a library or executable. -When compiling a single `.rs` file, the file acts as the whole crate. +When compiling a single `.rs` source file, the file acts as the whole crate. You can compile it with the `--lib` compiler switch to create a shared library, or without, provided that your file contains a `fn main` somewhere, to create an executable. -Larger crates typically span multiple files and are compiled from -a crate (.rc) file. Crate files contain their own syntax for loading -modules from .rs files and typically include metadata about the crate. +Larger crates typically span multiple files and are, by convention, +compiled from a source file with the `.rc` extension, called a *crate file*. +The crate file extension is used to distinguish source files that represent +crates from those that do not, but otherwise source files and crate files are identical. + +A typical crate file will declare attributes associated with the crate that +may affect how the compiler processes the source. +Crate attributes specify metadata used for locating and linking crates, +the type of crate (library or executable), +and control warning and error behavior, +among other things. +Crate files additionally declare the external crates they depend on +as well as any modules loaded from other files. ~~~~ { .xfail-test } +// Crate linkage metadata #[link(name = "farm", vers = "2.5", author = "mjh")]; + +// Make a library ("bin" is the default) #[crate_type = "lib"]; +// Turn on a warning +#[warn(non_camel_case_types)] + +// Link to the standard library +extern mod std; + +// Load some modules from other files mod cow; mod chicken; mod horse; + +fn main() { + ... +} ~~~~ Compiling this file will cause `rustc` to look for files named @@ -2282,7 +2306,7 @@ module, which other crates can use to load the right module. More about that later. To have a nested directory structure for your source files, you can -nest mods in your `.rc` file: +nest mods; ~~~~ {.ignore} mod poultry { @@ -2296,30 +2320,6 @@ The compiler will now look for `poultry/chicken.rs` and and `poultry::turkey`. You can also provide a `poultry.rs` to add content to the `poultry` module itself. -When compiling .rc files, if rustc finds a .rs file with the same -name, then that .rs file provides the top-level content of the crate. - -~~~ {.xfail-test} -// foo.rc -#[link(name = "foo", vers="1.0")]; - -mod bar; -~~~ - -~~~ {.xfail-test} -// foo.rs -fn main() { bar::baz(); } -~~~ - -> ***Note***: The way rustc looks for .rs files to pair with .rc -> files is a major source of confusion and will change. It's likely -> that the crate and source file grammars will merge. - -> ***Note***: The way that directory modules are handled will also -> change. The code for directory modules currently lives in a .rs -> file with the same name as the directory, _next to_ the directory. -> A new scheme will make that file live _inside_ the directory. - ## Using other crates The `extern mod` directive lets you use a crate (once it's been