]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #8777 : Kimundi/rust/doc_stuff, r=cmr
authorbors <bors@rust-lang.org>
Tue, 27 Aug 2013 13:45:50 +0000 (06:45 -0700)
committerbors <bors@rust-lang.org>
Tue, 27 Aug 2013 13:45:50 +0000 (06:45 -0700)
1  2 
doc/tutorial.md

diff --combined doc/tutorial.md
index 5737c3d8dcb6f23b73a4214fa1850f69aae6387c,051de260a098c0d6b38b71fc5ad315ed39cb4519..7614e8482377c458cde8fe2c38dd9bb059a5a387
@@@ -2251,237 -2251,665 +2251,665 @@@ The full list of derivable traits is `E
  `TotalOrd`, `Encodable` `Decodable`, `Clone`, `DeepClone`,
  `IterBytes`, `Rand`, `Zero`, and `ToStr`.
  
- # Modules and crates
+ # Crates and the module system
  
- The Rust namespace is arranged in a hierarchy of modules. Each source
- (.rs) file represents a single module and may in turn contain
- additional modules.
+ Rust's module system is very powerful, but because of that also somewhat complex.
+ Nevertheless, this section will try to explain every important aspect of it.
+ ## Crates
+ In order to speak about the module system, we first need to define the medium it exists in:
+ Let's say you've written a program or a library, compiled it, and got the resulting binary.
+ In Rust, the content of all source code that the compiler directly had to compile in order to end up with
+ that binary is collectively called a 'crate'.
+ For example, for a simple hello world program your crate only consists of this code:
+ ~~~~
+ // main.rs
+ fn main() {
+     println("Hello world!");
+ }
+ ~~~~
+ A crate is also the unit of independent compilation in Rust: `rustc` always compiles a single crate at a time,
+ from which it produces either a library or an executable.
+ Note that merely using an already compiled library in your code does not make it part of your crate.
+ ## The module hierarchy
+ For every crate, all the code in it is arranged in a hierarchy of modules starting with a single
+ root module. That root module is called the 'crate root'.
+ All modules in a crate below the crate root are declared with the `mod` keyword:
  
  ~~~~
+ // This is the crate root
  mod farm {
-     pub fn chicken() -> &str { "cluck cluck" }
-     pub fn cow() -> &str { "mooo" }
+     // This is the body of module 'farm' declared in the crate root.
+     fn chicken() { println("cluck cluck"); }
+     fn cow() { println("mooo"); }
+     mod barn {
+         // Body of module 'barn'
+         fn hay() { println("..."); }
+     }
  }
  
  fn main() {
-     println(farm::chicken());
+     println("Hello farm!");
  }
  ~~~~
  
- The contents of modules can be imported into the current scope
- with the `use` keyword, optionally giving it an alias. `use`
- may appear at the beginning of crates, `mod`s, `fn`s, and other
- blocks.
+ As you can see, your module hierarchy is now three modules deep: There is the crate root, which contains your `main()`
+ function, and the module `farm`. The module `farm` also contains two functions and a third module `barn`,
+ which contains a function `hay`.
  
- ~~~
- # mod farm { pub fn chicken() { } }
- # fn main() {
- // Bring `chicken` into scope
- use farm::chicken;
+ (In case you already stumbled over `extern mod`: It isn't directly related to a bare `mod`, we'll get to it later. )
+ ## Paths and visibility
  
- fn chicken_farmer() {
-     // The same, but name it `my_chicken`
-     use my_chicken = farm::chicken;
-     ...
- # my_chicken();
+ We've now defined a nice module hierarchy. But how do we access the items in it from our `main` function?
+ One way to do it is to simply fully qualifying it:
+ ~~~~ {.xfail-test}
+ mod farm {
+     fn chicken() { println("cluck cluck"); }
+     // ...
  }
- # chicken();
- # }
- ~~~
  
- These farm animal functions have a new keyword, `pub`, attached to
- them. The `pub` keyword modifies an item's visibility, making it
- visible outside its containing module. An expression with `::`, like
- `farm::chicken`, can name an item outside of its containing
- module. Items, such as those declared with `fn`, `struct`, `enum`,
- `type`, or `static`, are module-private by default.
+ fn main() {
+     println("Hello chicken!");
+     ::farm::chicken(); // Won't compile yet, see further down
+ }
+ ~~~~
+ The `::farm::chicken` construct is what we call a 'path'.
+ Because it's starting with a `::`, it's also a 'global path',
+ which qualifies an item by its full path in the module hierarchy
+ relative to the crate root.
+ If the path were to start with a regular identifier, like `farm::chicken`, it would be
+ a 'local path' instead. We'll get to them later.
+ Now, if you actually tried to compile this code example, you'll notice
+ that you get a `unresolved name: 'farm::chicken'` error. That's because per default,
+ items (`fn`, `struct`, `static`, `mod`, ...) are only visible inside the module
+ they are defined in.
+ To make them visible outside their containing modules, you need to mark them _public_ with `pub`:
+ ~~~~
+ mod farm {
+     pub fn chicken() { println("cluck cluck"); }
+     pub fn cow() { println("mooo"); }
+     // ...
+ }
+ fn main() {
+     println("Hello chicken!");
+     ::farm::chicken(); // This compiles now
+ }
+ ~~~~
  
  Visibility restrictions in Rust exist only at module boundaries. This
  is quite different from most object-oriented languages that also
  enforce restrictions on objects themselves. That's not to say that
  Rust doesn't support encapsulation: both struct fields and methods can
  be private. But this encapsulation is at the module level, not the
- struct level. Note that fields and methods are _public_ by default.
+ struct level.
+ For convenience, fields are _public_ by default, and can be made _private_ with the `priv` keyword:
  
  ~~~
pub mod farm {
+ mod farm {
  # pub type Chicken = int;
- # type Cow = int;
  # struct Human(int);
  # impl Human { fn rest(&self) { } }
- # pub fn make_me_a_farm() -> Farm { Farm { chickens: ~[], cows: ~[], farmer: Human(0) } }
+ # pub fn make_me_a_farm() -> Farm { Farm { chickens: ~[], farmer: Human(0) } }
      pub struct Farm {
          priv chickens: ~[Chicken],
-         priv cows: ~[Cow],
          farmer: Human
      }
  
      impl Farm {
          fn feed_chickens(&self) { ... }
-         fn feed_cows(&self) { ... }
          pub fn add_chicken(&self, c: Chicken) { ... }
      }
  
      pub fn feed_animals(farm: &Farm) {
          farm.feed_chickens();
-         farm.feed_cows();
      }
  }
  
  fn main() {
-      let f = make_me_a_farm();
-      f.add_chicken(make_me_a_chicken());
-      farm::feed_animals(&f);
-      f.farmer.rest();
+     let f = make_me_a_farm();
+     f.add_chicken(make_me_a_chicken());
+     farm::feed_animals(&f);
+     f.farmer.rest();
+     // This wouldn't compile because both are private:
+     // f.feed_chickens();
+     // let chicken_counter = f.chickens.len();
  }
  # fn make_me_a_farm() -> farm::Farm { farm::make_me_a_farm() }
  # fn make_me_a_chicken() -> farm::Chicken { 0 }
  ~~~
  
- ## Crates
+ > ***Note:*** Visibility rules are currently buggy and not fully defined, you might have to add or remove `pub` along a path until it works.
  
- 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 an executable.
- 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, by convention,
- compiled from a source file with the `.rc` extension, called a *crate file*.
- The crate file extension distinguishes source files that represent
- crates from those that do not, but otherwise source files and crate files are identical.
- A typical crate file declares 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")];
+ ## Files and modules
  
- // Make a library ("bin" is the default)
- #[crate_type = "lib"];
+ One important aspect about Rusts module system is that source files are not important:
+ You define a module hierarchy, populate it with all your definitions, define visibility,
+ maybe put in a `fn main()`, and that's it: No need to think about source files.
  
- // Turn on a warning
- #[warn(non_camel_case_types)]
+ The only file that's relevant is the one that contains the body of your crate root,
+ and it's only relevant because you have to pass that file to `rustc` to compile your crate.
  
- // Link to the standard library
- extern mod std;
+ And in principle, that's all you need: You can write any Rust program as one giant source file that contains your
+ crate root and everything below it in `mod ... { ... }` declarations.
+ However, in practice you usually want to split you code up into multiple source files to make it more manageable.
+ In order to do that, Rust allows you to move the body of any module into it's own source file, which works like this:
  
- // Load some modules from other files
- mod cow;
- mod chicken;
- mod horse;
+ If you declare a module without its body, like `mod foo;`, the compiler will look for the
+ files `foo.rs` and `foo/mod.rs`. If it finds either, it uses the content of that file as the body of the module.
+ If it finds both, that's a compile error.
+ So, if we want to move the content of `mod farm` into it's own file, it would look like this:
+ ~~~~ {.ignore}
+ // main.rs - contains body of the crate root
+ mod farm; // Compiler will look for 'farm.rs' and 'farm/mod.rs'
  
  fn main() {
-     ...
+     println("Hello farm!");
+     ::farm::cow();
  }
  ~~~~
  
- Compiling this file will cause `rustc` to look for files named
- `cow.rs`, `chicken.rs`, and `horse.rs` in the same directory as the
- `.rc` file, compile them all together, and, based on the presence of
- the `crate_type = "lib"` attribute, output a shared library or an
- executable. (If the line `#[crate_type = "lib"];` was omitted,
- `rustc` would create an executable.)
+ ~~~~
+ // farm.rs - contains body of module 'farm' in the crate root
+ pub fn chicken() { println("cluck cluck"); }
+ pub fn cow() { println("mooo"); }
  
- The `#[link(...)]` attribute provides meta information about the
- module, which other crates can use to load the right module. More
- about that later.
+ pub mod barn {
+     pub fn hay() { println("..."); }
+ }
+ # fn main() { }
+ ~~~~
  
- To have a nested directory structure for your source files, you can
- nest mods:
+ So, in short `mod foo;` is just syntactic sugar for `mod foo { /* include content of foo.rs or foo/mod.rs here */ }`.
  
- ~~~~ {.ignore}
- mod poultry {
-     mod chicken;
-     mod turkey;
+ This also means that having two or more identical `mod foo;` somewhere
+ in your crate hierarchy is generally a bad idea,
+ just like copy-and-paste-ing a module into two or more places is one.
+ Both will result in duplicate and mutually incompatible definitions.
+ The directory the compiler looks in for those two files is determined by starting with
+ the same directory as the source file that contains the `mod foo;` declaration, and concatenating to that a
+ path equivalent to the relative path of all nested `mod { ... }` declarations the `mod foo;` is contained in, if any.
+ For example, given a file with this module body:
+ ~~~ {.ignore}
+ // src/main.rs
+ mod plants;
+ mod fungi;
+ mod animals {
+     mod fish;
+     mod mammals {
+         mod humans;
+     }
+ }
+ ~~~
+ The compiler would then try all these files:
+ ~~~ {.notrust}
+ src/plants.rs
+ src/plants/mod.rs
+ src/fungi.rs
+ src/fungi/mod.rs
+ src/animals/fish.rs
+ src/animals/fish/mod.rs
+ src/animals/mammals/humans.rs
+ src/animals/mammals/humans/mod.rs
+ ~~~
+ These rules per default result in any directory structure mirroring
+ the crates's module hierarchy, and allow you to have both small modules that only need
+ to consist of one source file, and big modules that group the source files of submodules together.
+ If you need to circumvent those defaults, you can also overwrite the path a `mod foo;` would take:
+ ~~~ {.ignore}
+ #[path="../../area51/classified.rs"]
+ mod alien;
+ ~~~
+ ## Importing names into the local scope
+ Always referring to definitions in other modules with their global
+ path gets old really fast, so Rust has a way to import
+ them into the local scope of your module: `use`-statements.
+ They work like this: At the beginning of any module body, `fn` body, or any other block
+ you can write a list of `use`-statements, consisting of the keyword `use` and a __global path__ to an item
+ without the `::` prefix. For example, this imports `cow` into the local scope:
+ ~~~
+ use farm::cow;
+ # mod farm { pub fn cow() { println("I'm a hidden ninja cow!") } }
+ # fn main() { cow() }
+ ~~~
+ The path you give to `use` is per default global, meaning relative to the crate root,
+ no matter how deep the module hierarchy is, or whether the module body it's written in
+ is contained in its own file (remember: files are irrelevant).
+ This is different to other languages, where you often only find a single import construct that combines the semantic
+ of `mod foo;` and `use`-statements, and which tend to work relative to the source file or use an absolute file path
+ - Rubys `require` or C/C++'s `#include` come to mind.
+ However, it's also possible to import things relative to the module of the `use`-statement:
+ Adding a `super::` in front of the path will start in the parent module,
+ while adding a `self::` prefix will start in the current module:
+ ~~~
+ # mod workaround {
+ # pub fn some_parent_item(){ println("...") }
+ # mod foo {
+ use super::some_parent_item;
+ use self::some_child_module::some_item;
+ # pub fn bar() { some_parent_item(); some_item() }
+ # pub mod some_child_module { pub fn some_item() {} }
+ # }
+ # }
+ ~~~
+ Again - relative to the module, not to the file.
+ Imports are also shadowed by local definitions:
+ For each name you mention in a module/block, `rust`
+ will first look at all items that are defined locally,
+ and only if that results in no match look at items you brought in
+ scope with corresponding `use` statements.
+ ~~~ {.ignore}
+ # // XXX: Allow unused import in doc test
+ use farm::cow;
+ // ...
+ # mod farm { pub fn cow() { println("Hidden ninja cow is hidden.") } }
+ fn cow() { println("Mooo!") }
+ fn main() {
+     cow() // resolves to the locally defined cow() function
  }
+ ~~~
+ To make this behavior more obvious, the rule has been made that `use`-statement always need to be written
+ before any declaration, like in the example above. This is a purely artificial rule introduced
+ because people always assumed they shadowed each other based on order, despite the fact that all items in rust are
+ mutually recursive, order independent definitions.
+ One odd consequence of that rule is that `use` statements also go in front of any `mod` declaration,
+ even if they refer to things inside them:
+ ~~~
+ use farm::cow;
+ mod farm {
+     pub fn cow() { println("Moooooo?") }
+ }
+ fn main() { cow() }
+ ~~~
+ This is what our `farm` example looks like with `use` statements:
  ~~~~
+ use farm::chicken;
+ use farm::cow;
+ use farm::barn;
  
- The compiler will now look for `poultry/chicken.rs` and
- `poultry/turkey.rs`, and export their content in `poultry::chicken`
- and `poultry::turkey`. You can also provide a `poultry.rs` to add
- content to the `poultry` module itself.
+ mod farm {
+     pub fn chicken() { println("cluck cluck"); }
+     pub fn cow() { println("mooo"); }
  
- ## Using other crates
+     pub mod barn {
+         pub fn hay() { println("..."); }
+     }
+ }
  
- The `extern mod` directive lets you use a crate (once it's been
- compiled into a library) from inside another crate. `extern mod` can
- appear at the top of a crate file or at the top of modules. It will
- cause the compiler to look in the library search path (which you can
- extend with the `-L` switch) for a compiled Rust library with the
- right name, then add a module with that crate's name into the local
- scope.
+ fn main() {
+     println("Hello farm!");
  
- For example, `extern mod std` links the [standard library].
+     // Can now refer to those names directly:
+     chicken();
+     cow();
+     barn::hay();
+ }
+ ~~~~
  
- [standard library]: std/index.html
+ And here an example with multiple files:
+ ~~~{.ignore}
+ // a.rs - crate root
+ use b::foo;
+ mod b;
+ fn main() { foo(); }
+ ~~~
+ ~~~{.ignore}
+ // b.rs
+ use b::c::bar;
+ pub mod c;
+ pub fn foo() { bar(); }
+ ~~~
+ ~~~
+ // c.rs
+ pub fn bar() { println("Baz!"); }
+ ~~~
  
- When a comma-separated list of name/value pairs appears after `extern
- mod`, the compiler front-end matches these pairs against the
- attributes provided in the `link` attribute of the crate file. The
- front-end will only select this crate for use if the actual pairs
- match the declared attributes. You can provide a `name` value to
- override the name used to search for the crate.
+ There also exist two short forms for importing multiple names at once:
  
- Our example crate declared this set of `link` attributes:
+ 1. Explicit mention multiple names as the last element of an `use` path:
+ ~~~
+ use farm::{chicken, cow};
+ # mod farm {
+ #     pub fn cow() { println("Did I already mention how hidden and ninja I am?") }
+ #     pub fn chicken() { println("I'm Bat-chicken, guardian of the hidden tutorial code.") }
+ # }
+ # fn main() { cow(); chicken() }
+ ~~~
+ 2. Import everything in a module with a wildcard:
+ ~~~
+ use farm::*;
+ # mod farm {
+ #     pub fn cow() { println("Bat-chicken? What a stupid name!") }
+ #     pub fn chicken() { println("Says the 'hidden ninja' cow.") }
+ # }
+ # fn main() { cow(); chicken() }
+ ~~~
+ However, that's not all. You can also rename an item while you're bringing it into scope:
+ ~~~
+ use egg_layer = farm::chicken;
+ # mod farm { pub fn chicken() { println("Laying eggs is fun!")  } }
+ // ...
+ fn main() {
+     egg_layer();
+ }
+ ~~~
+ In general, `use` creates an local alias:
+ An alternate path and a possibly different name to access the same item,
+ whiteout touching the original, and with both being interchangeable.
+ ## Reexporting names
+ It is also possible to reexport items to be accessible under your module.
+ For that, you write `pub use`:
+ ~~~
+ mod farm {
+     pub use self::barn::hay;
+     pub fn chicken() { println("cluck cluck"); }
+     pub fn cow() { println("mooo"); }
+     mod barn {
+         pub fn hay() { println("..."); }
+     }
+ }
+ fn main() {
+     farm::chicken();
+     farm::cow();
+     farm::hay();
+ }
+ ~~~
+ Just like in normal `use` statements, the exported names
+ merely represent an alias to the same thing and can also be renamed.
+ The above example also demonstrate what you can use `pub use` for:
+ The nested `barn` module is private, but the `pub use` allows users
+ of the module `farm` to access a function from `barn` without needing
+ to know that `barn` exists.
+ In other words, you can use them to decouple an public api from their internal implementation.
+ ## Using libraries
+ So far we've only talked about how to define and structure your own crate.
+ However, most code out there will want to use preexisting libraries,
+ as there really is no reason to start from scratch each time you start a new project.
+ In Rust terminology, we need a way to refer to other crates.
+ For that, Rust offers you the `extern mod` declaration:
+ ~~~
+ extern mod extra;
+ // extra ships with Rust, you'll find more details further down.
+ fn main() {
+     // The rational number '1/2':
+     let one_half = ::extra::rational::Ratio::new(1, 2);
+ }
+ ~~~
+ Despite its name, `extern mod` is a distinct construct from regular `mod` declarations:
+ A statement of the form `extern mod foo;` will cause `rustc` to search for the crate `foo`,
+ and if it finds a matching binary it lets you use it from inside your crate.
+ The effect it has on your module hierarchy mirrors aspects of both `mod` and `use`:
+ - Like `mod`, it causes `rustc` to actually emit code:
+   The linkage information the binary needs to use the library `foo`.
+ - But like `use`, all `extern mod` statements that refer to the same library are interchangeable,
+   as each one really just presents an alias to an external module (the crate root of the library your linking against).
+ Remember how `use`-statements have to go before local declarations because the latter shadows the former?
+ Well, `extern mod` statements also have their own rules in that regard:
+ Both `use` and local declarations can shadow them, so the rule is that `extern mod` has to go in front
+ of both `use` and local declarations.
+ Which can result in something like this:
+ ~~~
+ extern mod extra;
+ use farm::dog;
+ use extra::rational::Ratio;
+ mod farm {
+     pub fn dog() { println("woof"); }
+ }
+ fn main() {
+     farm::dog();
+     let a_third = Ratio::new(1, 3);
+ }
+ ~~~
+ It's a bit weird, but it's the result of shadowing rules that have been set that way because
+ they model most closely what people expect to shadow.
+ ## Package ids
+ If you use `extern mod`, per default `rustc` will look for libraries in the the library search path (which you can
+ extend with the `-L` switch).
+ However, Rust also ships with rustpkg, a package manager that is able to automatically download and build
+ libraries if you use it for building your crate. How it works is explained [here][rustpkg],
+ but for this tutorial it's only important to know that you can optionally annotate an
+ `extern mod` statement with an package id that rustpkg can use to identify it:
+ ~~~ {.ignore}
+ extern mod rust = "github.com/mozilla/rust"; // pretend Rust is an simple library
+ ~~~
+ [rustpkg]: rustpkg.html
+ ## Crate metadata and settings
+ For every crate you can define a number of metadata items, such as link name, version or author.
+ You can also toggle settings that have crate-global consequences. Both mechanism
+ work by providing attributes in the crate root.
+ For example, Rust uniquely identifies crates by their link metadate, which includes
+ the link name and the version. It also hashes the filename and the symbols in a binary
+ based on the link metadata, allowing you to use two different versions of the same library in a crate
+ without conflict.
+ Therefor, if you plan to compile your crate as a library, you should annotate it with that information:
  
  ~~~~
- #[link(name = "farm", vers = "2.5", author = "mjh")];
+ // lib.rs
+ # #[crate_type = "lib"];
+ // Crate linkage metadata
+ #[link(name = "farm", vers = "2.5")];
+ // ...
+ # pub fn farm() {}
  ~~~~
  
- Which you can then link with any (or all) of the following:
+ You can also in turn require in a `extern mod` statement that certain link metadata items match some criteria.
+ For that, Rust currently parses a comma-separated list of name/value pairs that appear after
+ it, and ensures that they match the attributes provided in the `link` attribute of a crate file.
+ This enables you to, eg, pick a a crate based on it's version number, or to link an library under an
+ different name. For example, this two mod statements would both accept and select the crate define above:
  
  ~~~~ {.xfail-test}
- extern mod farm;
- extern mod my_farm (name = "farm", vers = "2.5");
- extern mod my_auxiliary_farm (name = "farm", author = "mjh");
+ extern mod farm(vers = "2.5");
+ extern mod my_farm(name = "farm", vers = "2.5");
+ ~~~~
+ Other crate settings and metadata include things like enabling/disabling certain errors or warnings,
+ or setting the crate type (library or executable) explicitly:
  ~~~~
+ // lib.rs
+ // ...
  
- If any of the requested metadata do not match, then the crate
- will not be compiled successfully.
+ // This crate is a library ("bin" is the default)
+ #[crate_type = "lib"];
+ // Turn on a warning
+ #[warn(non_camel_case_types)]
+ # pub fn farm() {}
+ ~~~~
+ If you're compiling your crate with `rustpkg`,
+ link annotations will not be necessary, because they get
+ inferred by `rustpkg` based on the Package id and naming conventions.
+ > ***Note:*** The rules regarding link metadata, both as attributes and on `extern mod`,
+               as well as their interaction with `rustpkg`
+               are currently not clearly defined and will likely change in the future.
  
  ## A minimal example
  
- Now for something that you can actually compile yourself, we have
- these two files:
+ Now for something that you can actually compile yourself.
+ We define two crates, and use one of them as a library in the other.
  
  ~~~~
  // world.rs
- #[link(name = "world", vers = "1.0")];
- pub fn explore() -> &str { "world" }
+ #[link(name = "world", vers = "0.42")];
+ pub fn explore() -> &'static str { "world" }
  ~~~~
  
  ~~~~ {.xfail-test}
  // main.rs
  extern mod world;
- fn main() { println(~"hello " + world::explore()); }
+ fn main() { println("hello " + world::explore()); }
  ~~~~
  
  Now compile and run like this (adjust to your platform if necessary):
  
  ~~~~ {.notrust}
- > rustc --lib world.rs  # compiles libworld-94839cbfe144198-1.0.so
+ > rustc --lib world.rs  # compiles libworld-<HASH>-0.42.so
  > rustc main.rs -L .    # compiles main
  > ./main
  "hello world"
  ~~~~
  
- Notice that the library produced contains the version in the filename
- as well as an inscrutable string of alphanumerics. These are both
- part of Rust's library versioning scheme. The alphanumerics are
- a hash representing the crate metadata.
+ Notice that the library produced contains the version in the file name
+ as well as an inscrutable string of alphanumerics. As explained in the previous paragraph,
+ these are both part of Rust's library versioning scheme. The alphanumerics are
+ a hash representing the crates link metadata.
+ ## The standard library and the prelude
+ While reading the examples in this tutorial, you might have asked yourself where all
+ those magical predefined items like `println()` are coming from.
+ The truth is, there's nothing magical about them: They are all defined normally
+ in the `std` library, which is a crate that ships with Rust.
+ The only magical thing that happens is that `rustc` automatically inserts this line into your crate root:
+ ~~~ {.ignore}
+ extern mod std;
+ ~~~
+ As well as this line into every module body:
+ ~~~ {.ignore}
+ use std::prelude::*;
+ ~~~
+ The role of the `prelude` module is to re-exports common definitions from `std`.
+ This allows you to use common types and functions like `Option<T>` or `println`
+ without needing to import them. And if you need something from `std` that's not in the prelude,
+ you just have to import it with an `use` statement.
+ For example, it re-exports `println` which is defined in `std::io::println`:
+ ~~~
+ use puts = std::io::println;
+ fn main() {
+     println("println is imported per default.");
+     puts("Doesn't hinder you from importing it under an different name yourself.");
+     ::std::io::println("Or from not using the automatic import.");
+ }
+ ~~~
+ Both auto-insertions can be disabled with an attribute if necessary:
+ ~~~
+ // In the crate root:
+ #[no_std];
+ ~~~
+ ~~~
+ // In any module:
+ #[no_implicit_prelude];
+ ~~~
  
- ## The standard library
+ ## The standard library in detail
  
  The Rust standard library provides runtime features required by the language,
  including the task scheduler and memory allocators, as well as library
@@@ -2499,24 -2927,9 +2927,9 @@@ I/O abstractions ([`io`]), [containers
  common traits ([`kinds`], [`ops`], [`cmp`], [`num`],
  [`to_str`], [`clone`]), and complete bindings to the C standard library ([`libc`]).
  
- ### Standard Library injection and the Rust prelude
- `std` is imported at the topmost level of every crate by default, as
- if the first line of each crate was
-     extern mod std;
- This means that the contents of std can be accessed from from any context
- with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`,
- etc.
- Additionally, `std` contains a `prelude` module that reexports many of the
- most common standard modules, types and traits. The contents of the prelude are
- imported into every *module* by default.  Implicitly, all modules behave as if
- they contained the following prologue:
-     use std::prelude::*;
+ The full documentation for `std` can be found here: [standard library].
  
+ [standard library]: std/index.html
  [`std`]: std/index.html
  [`bool`]: std/bool.html
  [tuples]: std/tuple.html
  [`clone`]: std/clone.html
  [`libc`]: std/libc.html
  
+ ## The extra library
+ Rust also ships with the [extra library], an accumulation of
+ useful things, that are however not important enough
+ to deserve a place in the standard library.
+ You can use them by linking to `extra` with an `extern mod extra;`.
+ [extra library]: extra/index.html
+ Right now `extra` contains those definitions directly, but in the future it will likely just
+ re-export a bunch of 'officially blessed' crates that get managed with `rustpkg`.
  # What next?
  
  Now that you know the essentials, check out any of the additional
@@@ -2553,9 -2978,8 +2978,9 @@@ tutorials on individual topics
  * [Macros][macros]
  * [The foreign function interface][ffi]
  * [Containers and iterators](tutorial-container.html)
 +* [Error-handling and Conditions](tutorial-conditions.html)
  
- There is further documentation on the [wiki].
+ There is further documentation on the [wiki], however those tend to be even more out of date as this document.
  
  [borrow]: tutorial-borrowed-ptr.html
  [tasks]: tutorial-tasks.html