From 7541f82faba6b2839b5e640605d7caab6cc6ec4f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 8 Jan 2015 10:27:03 -0800 Subject: [PATCH] Fix dead links in the guide and reorganize --- mk/docs.mk | 5 +- mk/tests.mk | 4 +- src/doc/trpl/SUMMARY.md | 67 ++- src/doc/trpl/{src => }/advanced.md | 0 .../{src => }/arrays-vectors-and-slices.md | 4 +- src/doc/trpl/{src => }/basic.md | 0 src/doc/trpl/{src => }/closures.md | 2 +- src/doc/trpl/{src => }/comments.md | 4 +- src/doc/trpl/{src => }/compound-data-types.md | 2 +- src/doc/trpl/{src => }/conclusion.md | 0 src/doc/trpl/{src => }/crates-and-modules.md | 0 src/doc/trpl/{src => }/error-handling.md | 0 src/doc/trpl/{src => }/ffi.md | 0 src/doc/trpl/{src => }/functions.md | 2 +- src/doc/trpl/{src => }/generics.md | 0 src/doc/trpl/{src => }/guessing-game.md | 8 +- src/doc/trpl/{src => }/hello-cargo.md | 2 +- src/doc/trpl/{src => }/hello-world.md | 2 +- src/doc/trpl/{src => }/if.md | 2 +- src/doc/trpl/{src => }/installing-rust.md | 2 +- src/doc/trpl/{src => }/intermediate.md | 0 src/doc/trpl/{src => }/iterators.md | 2 +- src/doc/trpl/{src => }/looping.md | 2 +- src/doc/trpl/{src => }/macros.md | 4 +- src/doc/trpl/{src => }/match.md | 2 +- src/doc/trpl/{src => }/method-syntax.md | 0 src/doc/trpl/{src => }/ownership.md | 0 src/doc/trpl/{src => }/patterns.md | 0 src/doc/trpl/{src => }/plugins.md | 47 +- src/doc/trpl/{src => }/pointers.md | 8 +- src/doc/trpl/src/guide-lifetimes.md | 565 ------------------ src/doc/trpl/{src => }/standard-input.md | 2 +- src/doc/trpl/{src => }/strings.md | 2 +- src/doc/trpl/{src => }/tasks.md | 2 +- src/doc/trpl/{src => }/testing.md | 0 src/doc/trpl/{src => }/traits.md | 0 src/doc/trpl/{src => }/unsafe.md | 8 +- src/doc/trpl/{src => }/variable-bindings.md | 4 +- src/rustbook/book.rs | 8 +- src/rustbook/build.rs | 11 +- src/rustbook/error.rs | 6 + src/rustbook/main.rs | 0 src/rustbook/term.rs | 2 + 43 files changed, 112 insertions(+), 669 deletions(-) rename src/doc/trpl/{src => }/advanced.md (100%) rename src/doc/trpl/{src => }/arrays-vectors-and-slices.md (96%) rename src/doc/trpl/{src => }/basic.md (100%) rename src/doc/trpl/{src => }/closures.md (99%) rename src/doc/trpl/{src => }/comments.md (93%) rename src/doc/trpl/{src => }/compound-data-types.md (99%) rename src/doc/trpl/{src => }/conclusion.md (100%) rename src/doc/trpl/{src => }/crates-and-modules.md (100%) rename src/doc/trpl/{src => }/error-handling.md (100%) rename src/doc/trpl/{src => }/ffi.md (100%) rename src/doc/trpl/{src => }/functions.md (99%) rename src/doc/trpl/{src => }/generics.md (100%) rename src/doc/trpl/{src => }/guessing-game.md (98%) rename src/doc/trpl/{src => }/hello-cargo.md (99%) rename src/doc/trpl/{src => }/hello-world.md (99%) rename src/doc/trpl/{src => }/if.md (99%) rename src/doc/trpl/{src => }/installing-rust.md (99%) rename src/doc/trpl/{src => }/intermediate.md (100%) rename src/doc/trpl/{src => }/iterators.md (99%) rename src/doc/trpl/{src => }/looping.md (99%) rename src/doc/trpl/{src => }/macros.md (99%) rename src/doc/trpl/{src => }/match.md (99%) rename src/doc/trpl/{src => }/method-syntax.md (100%) rename src/doc/trpl/{src => }/ownership.md (100%) rename src/doc/trpl/{src => }/patterns.md (100%) rename src/doc/trpl/{src => }/plugins.md (81%) rename src/doc/trpl/{src => }/pointers.md (98%) delete mode 100644 src/doc/trpl/src/guide-lifetimes.md rename src/doc/trpl/{src => }/standard-input.md (99%) rename src/doc/trpl/{src => }/strings.md (99%) rename src/doc/trpl/{src => }/tasks.md (99%) rename src/doc/trpl/{src => }/testing.md (100%) rename src/doc/trpl/{src => }/traits.md (100%) rename src/doc/trpl/{src => }/unsafe.md (98%) rename src/doc/trpl/{src => }/variable-bindings.md (98%) mode change 100755 => 100644 src/rustbook/build.rs mode change 100755 => 100644 src/rustbook/main.rs diff --git a/mk/docs.mk b/mk/docs.mk index a84977b382b..1104c3eb6db 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -275,9 +275,8 @@ endif docs: $(DOC_TARGETS) compiler-docs: $(COMPILER_DOC_TARGETS) -trpl: tmp/trpl.ok +trpl: doc/book/index.html -tmp/trpl.ok: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/trpl/*.md) +doc/book/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/trpl/*.md) $(Q)rm -rf doc/book $(Q)$(RUSTBOOK) build $(S)src/doc/trpl doc/book - $(Q)touch $@ diff --git a/mk/tests.mk b/mk/tests.mk index 97455e744d4..c8c4beb1153 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -156,8 +156,8 @@ endef $(foreach doc,$(DOCS), \ $(eval $(call DOCTEST,md-$(doc),$(S)src/doc/$(doc).md))) -$(foreach file,$(wildcard $(S)src/doc/trpl/src/*), \ - $(eval $(call DOCTEST,$(file:$(S)src/doc/trpl/src/%.md=trpl-%),$(file)))) +$(foreach file,$(wildcard $(S)src/doc/trpl/*.md), \ + $(eval $(call DOCTEST,$(file:$(S)src/doc/trpl/%.md=trpl-%),$(file)))) ###################################################################### # Main test targets diff --git a/src/doc/trpl/SUMMARY.md b/src/doc/trpl/SUMMARY.md index 0f1bce389df..1a61c6d216b 100644 --- a/src/doc/trpl/SUMMARY.md +++ b/src/doc/trpl/SUMMARY.md @@ -1,35 +1,36 @@ # Summary -* [I: The Basics](src/basic.md) - * [Installing Rust](src/installing-rust.md) - * [Hello, world!](src/hello-world.md) - * [Hello, Cargo!](src/hello-cargo.md) - * [Variable Bindings](src/variable-bindings.md) - * [If](src/if.md) - * [Functions](src/functions.md) - * [Comments](src/comments.md) - * [Compound Data Types](src/compound-data-types.md) - * [Match](src/match.md) - * [Looping](src/looping.md) - * [Strings](src/strings.md) - * [Arrays, Vectors, and Slices](src/arrays-vectors-and-slices.md) - * [Standard Input](src/standard-input.md) - * [Guessing Game](src/guessing-game.md) -* [II: Intermedite Rust](src/intermediate.md) - * [Crates and Modules](src/crates-and-modules.md) - * [Testing](src/testing.md) - * [Pointers](src/pointers.md) - * [Patterns](src/patterns.md) - * [Method Syntax](src/method-syntax.md) - * [Closures](src/closures.md) - * [Iterators](src/iterators.md) - * [Generics](src/generics.md) - * [Traits](src/traits.md) - * [Tasks](src/tasks.md) - * [Error Handling](src/error-handling.md) -* [III: Advanced Topics](src/advanced.md) - * [FFI](src/ffi.md) - * [Unsafe Code](src/unsafe.md) - * [Macros](src/macros.md) - * [Compiler Plugins](src/plugins.md) -* [Conclusion](src/conclusion.md) +* [I: The Basics](basic.md) + * [Installing Rust](installing-rust.md) + * [Hello, world!](hello-world.md) + * [Hello, Cargo!](hello-cargo.md) + * [Variable Bindings](variable-bindings.md) + * [If](if.md) + * [Functions](functions.md) + * [Comments](comments.md) + * [Compound Data Types](compound-data-types.md) + * [Match](match.md) + * [Looping](looping.md) + * [Strings](strings.md) + * [Arrays, Vectors, and Slices](arrays-vectors-and-slices.md) + * [Standard Input](standard-input.md) + * [Guessing Game](guessing-game.md) +* [II: Intermediate Rust](intermediate.md) + * [Crates and Modules](crates-and-modules.md) + * [Testing](testing.md) + * [Pointers](pointers.md) + * [Ownership](ownership.md) + * [Patterns](patterns.md) + * [Method Syntax](method-syntax.md) + * [Closures](closures.md) + * [Iterators](iterators.md) + * [Generics](generics.md) + * [Traits](traits.md) + * [Tasks](tasks.md) + * [Error Handling](error-handling.md) +* [III: Advanced Topics](advanced.md) + * [FFI](ffi.md) + * [Unsafe Code](unsafe.md) + * [Macros](macros.md) + * [Compiler Plugins](plugins.md) +* [Conclusion](conclusion.md) diff --git a/src/doc/trpl/src/advanced.md b/src/doc/trpl/advanced.md similarity index 100% rename from src/doc/trpl/src/advanced.md rename to src/doc/trpl/advanced.md diff --git a/src/doc/trpl/src/arrays-vectors-and-slices.md b/src/doc/trpl/arrays-vectors-and-slices.md similarity index 96% rename from src/doc/trpl/src/arrays-vectors-and-slices.md rename to src/doc/trpl/arrays-vectors-and-slices.md index 68fc73222fd..24d60dd2e4e 100644 --- a/src/doc/trpl/src/arrays-vectors-and-slices.md +++ b/src/doc/trpl/arrays-vectors-and-slices.md @@ -1,4 +1,4 @@ -# Arrays, Vectors, and Slices +% Arrays, Vectors, and Slices Like many programming languages, Rust has list types to represent a sequence of things. The most basic is the **array**, a fixed-size list of elements of the @@ -48,7 +48,7 @@ errant access is the source of many bugs in other systems programming languages. A **vector** is a dynamic or "growable" array, implemented as the standard -library type [`Vec`](std/vec/) (we'll talk about what the `` means +library type [`Vec`](../std/vec/) (we'll talk about what the `` means later). Vectors are to arrays what `String` is to `&str`. You can create them with the `vec!` macro: diff --git a/src/doc/trpl/src/basic.md b/src/doc/trpl/basic.md similarity index 100% rename from src/doc/trpl/src/basic.md rename to src/doc/trpl/basic.md diff --git a/src/doc/trpl/src/closures.md b/src/doc/trpl/closures.md similarity index 99% rename from src/doc/trpl/src/closures.md rename to src/doc/trpl/closures.md index 79ae28e1b91..6413b90ee71 100644 --- a/src/doc/trpl/src/closures.md +++ b/src/doc/trpl/closures.md @@ -1,4 +1,4 @@ -# Closures +% Closures So far, we've made lots of functions in Rust, but we've given them all names. Rust also allows us to create anonymous functions. Rust's anonymous diff --git a/src/doc/trpl/src/comments.md b/src/doc/trpl/comments.md similarity index 93% rename from src/doc/trpl/src/comments.md rename to src/doc/trpl/comments.md index cce6eacea04..f02c1ad9a18 100644 --- a/src/doc/trpl/src/comments.md +++ b/src/doc/trpl/comments.md @@ -1,4 +1,4 @@ -# Comments +% Comments Now that we have some functions, it's a good idea to learn about comments. Comments are notes that you leave to other programmers to help explain things @@ -42,5 +42,5 @@ fn hello(name: &str) { When writing doc comments, adding sections for any arguments, return values, and providing some examples of usage is very, very helpful. -You can use the [`rustdoc`](rustdoc.html) tool to generate HTML documentation +You can use the [`rustdoc`](../rustdoc.html) tool to generate HTML documentation from these doc comments. diff --git a/src/doc/trpl/src/compound-data-types.md b/src/doc/trpl/compound-data-types.md similarity index 99% rename from src/doc/trpl/src/compound-data-types.md rename to src/doc/trpl/compound-data-types.md index b9bb5097361..b80d248bc41 100644 --- a/src/doc/trpl/src/compound-data-types.md +++ b/src/doc/trpl/compound-data-types.md @@ -1,4 +1,4 @@ -# Compound Data Types +% Compound Data Types Rust, like many programming languages, has a number of different data types that are built-in. You've already done some simple work with integers and diff --git a/src/doc/trpl/src/conclusion.md b/src/doc/trpl/conclusion.md similarity index 100% rename from src/doc/trpl/src/conclusion.md rename to src/doc/trpl/conclusion.md diff --git a/src/doc/trpl/src/crates-and-modules.md b/src/doc/trpl/crates-and-modules.md similarity index 100% rename from src/doc/trpl/src/crates-and-modules.md rename to src/doc/trpl/crates-and-modules.md diff --git a/src/doc/trpl/src/error-handling.md b/src/doc/trpl/error-handling.md similarity index 100% rename from src/doc/trpl/src/error-handling.md rename to src/doc/trpl/error-handling.md diff --git a/src/doc/trpl/src/ffi.md b/src/doc/trpl/ffi.md similarity index 100% rename from src/doc/trpl/src/ffi.md rename to src/doc/trpl/ffi.md diff --git a/src/doc/trpl/src/functions.md b/src/doc/trpl/functions.md similarity index 99% rename from src/doc/trpl/src/functions.md rename to src/doc/trpl/functions.md index 0fa3c66af64..e3827d962c3 100644 --- a/src/doc/trpl/src/functions.md +++ b/src/doc/trpl/functions.md @@ -1,4 +1,4 @@ -# Functions +% Functions You've already seen one function so far, the `main` function: diff --git a/src/doc/trpl/src/generics.md b/src/doc/trpl/generics.md similarity index 100% rename from src/doc/trpl/src/generics.md rename to src/doc/trpl/generics.md diff --git a/src/doc/trpl/src/guessing-game.md b/src/doc/trpl/guessing-game.md similarity index 98% rename from src/doc/trpl/src/guessing-game.md rename to src/doc/trpl/guessing-game.md index 1efcd489760..2847964f15f 100644 --- a/src/doc/trpl/src/guessing-game.md +++ b/src/doc/trpl/guessing-game.md @@ -1,4 +1,4 @@ -# Guessing Game +% Guessing Game Okay! We've got the basics of Rust down. Let's write a bigger program. @@ -108,12 +108,12 @@ we do know that Rust has random number generation, but we don't know how to use it. Enter the docs. Rust has a page specifically to document the standard library. -You can find that page [here](std/index.html). There's a lot of information on +You can find that page [here](../std/index.html). There's a lot of information on that page, but the best part is the search bar. Right up at the top, there's a box that you can enter in a search term. The search is pretty primitive right now, but is getting better all the time. If you type 'random' in that -box, the page will update to [this one](std/index.html?search=random). The very -first result is a link to [`std::rand::random`](std/rand/fn.random.html). If we +box, the page will update to [this one](../std/index.html?search=random). The very +first result is a link to [`std::rand::random`](../std/rand/fn.random.html). If we click on that result, we'll be taken to its documentation page. This page shows us a few things: the type signature of the function, some diff --git a/src/doc/trpl/src/hello-cargo.md b/src/doc/trpl/hello-cargo.md similarity index 99% rename from src/doc/trpl/src/hello-cargo.md rename to src/doc/trpl/hello-cargo.md index c81cdc465c8..d8acd95b59d 100644 --- a/src/doc/trpl/src/hello-cargo.md +++ b/src/doc/trpl/hello-cargo.md @@ -1,4 +1,4 @@ -# Hello, Cargo! +% Hello, Cargo! [Cargo](http://crates.io) is a tool that Rustaceans use to help manage their Rust projects. Cargo is currently in an alpha state, just like Rust, and so it diff --git a/src/doc/trpl/src/hello-world.md b/src/doc/trpl/hello-world.md similarity index 99% rename from src/doc/trpl/src/hello-world.md rename to src/doc/trpl/hello-world.md index 33cb752c364..f9cc1ebf0bf 100644 --- a/src/doc/trpl/src/hello-world.md +++ b/src/doc/trpl/hello-world.md @@ -1,4 +1,4 @@ -# Hello, world! +% Hello, world! Now that you have Rust installed, let's write your first Rust program. It's traditional to make your first program in any new language one that prints the diff --git a/src/doc/trpl/src/if.md b/src/doc/trpl/if.md similarity index 99% rename from src/doc/trpl/src/if.md rename to src/doc/trpl/if.md index bc3d548ce9f..6f81a27b2b7 100644 --- a/src/doc/trpl/src/if.md +++ b/src/doc/trpl/if.md @@ -1,4 +1,4 @@ -# `if` +% `if` Rust's take on `if` is not particularly complex, but it's much more like the `if` you'll find in a dynamically typed language than in a more traditional diff --git a/src/doc/trpl/src/installing-rust.md b/src/doc/trpl/installing-rust.md similarity index 99% rename from src/doc/trpl/src/installing-rust.md rename to src/doc/trpl/installing-rust.md index 1705893c397..5893b51a420 100644 --- a/src/doc/trpl/src/installing-rust.md +++ b/src/doc/trpl/installing-rust.md @@ -1,4 +1,4 @@ -# Installing Rust +% Installing Rust The first step to using Rust is to install it! There are a number of ways to install Rust, but the easiest is to use the `rustup` script. If you're on diff --git a/src/doc/trpl/src/intermediate.md b/src/doc/trpl/intermediate.md similarity index 100% rename from src/doc/trpl/src/intermediate.md rename to src/doc/trpl/intermediate.md diff --git a/src/doc/trpl/src/iterators.md b/src/doc/trpl/iterators.md similarity index 99% rename from src/doc/trpl/src/iterators.md rename to src/doc/trpl/iterators.md index 056e9a9720e..a773b7329db 100644 --- a/src/doc/trpl/src/iterators.md +++ b/src/doc/trpl/iterators.md @@ -336,4 +336,4 @@ can help you with. There are a number of really useful iterators, and you can write your own as well. Iterators provide a safe, efficient way to manipulate all kinds of lists. They're a little unusual at first, but if you play with them, you'll get hooked. For a full list of the different iterators and -consumers, check out the [iterator module documentation](std/iter/index.html). +consumers, check out the [iterator module documentation](../std/iter/index.html). diff --git a/src/doc/trpl/src/looping.md b/src/doc/trpl/looping.md similarity index 99% rename from src/doc/trpl/src/looping.md rename to src/doc/trpl/looping.md index 03384b28703..80926c99e87 100644 --- a/src/doc/trpl/src/looping.md +++ b/src/doc/trpl/looping.md @@ -1,4 +1,4 @@ -# Looping +% Looping Looping is the last basic construct that we haven't learned yet in Rust. Rust has two main looping constructs: `for` and `while`. diff --git a/src/doc/trpl/src/macros.md b/src/doc/trpl/macros.md similarity index 99% rename from src/doc/trpl/src/macros.md rename to src/doc/trpl/macros.md index 95f5305775e..c694806b4ba 100644 --- a/src/doc/trpl/src/macros.md +++ b/src/doc/trpl/macros.md @@ -507,7 +507,7 @@ When this library is loaded with `#[use_macros] extern crate`, only `m2` will be imported. The Rust Reference has a [listing of macro-related -attributes](reference.html#macro--and-plugin-related-attributes). +attributes](../reference.html#macro--and-plugin-related-attributes). # The variable `$crate` @@ -567,7 +567,7 @@ intermediate states out, and passing the flag `--pretty expanded` as a command-line argument to the compiler will show the result of expansion. If Rust's macro system can't do what you need, you may want to write a -[compiler plugin](guide-plugin.html) instead. Compared to `macro_rules!` +[compiler plugin](plugin.html) instead. Compared to `macro_rules!` macros, this is significantly more work, the interfaces are much less stable, and the warnings about debugging apply ten-fold. In exchange you get the flexibility of running arbitrary Rust code within the compiler. Syntax diff --git a/src/doc/trpl/src/match.md b/src/doc/trpl/match.md similarity index 99% rename from src/doc/trpl/src/match.md rename to src/doc/trpl/match.md index 0170109def0..c120142cf5c 100644 --- a/src/doc/trpl/src/match.md +++ b/src/doc/trpl/match.md @@ -1,4 +1,4 @@ -# Match +% Match Often, a simple `if`/`else` isn't enough, because you have more than two possible options. Also, `else` conditions can get incredibly complicated, so diff --git a/src/doc/trpl/src/method-syntax.md b/src/doc/trpl/method-syntax.md similarity index 100% rename from src/doc/trpl/src/method-syntax.md rename to src/doc/trpl/method-syntax.md diff --git a/src/doc/trpl/src/ownership.md b/src/doc/trpl/ownership.md similarity index 100% rename from src/doc/trpl/src/ownership.md rename to src/doc/trpl/ownership.md diff --git a/src/doc/trpl/src/patterns.md b/src/doc/trpl/patterns.md similarity index 100% rename from src/doc/trpl/src/patterns.md rename to src/doc/trpl/patterns.md diff --git a/src/doc/trpl/src/plugins.md b/src/doc/trpl/plugins.md similarity index 81% rename from src/doc/trpl/src/plugins.md rename to src/doc/trpl/plugins.md index 025f0cced63..2a0710d018c 100644 --- a/src/doc/trpl/src/plugins.md +++ b/src/doc/trpl/plugins.md @@ -5,20 +5,20 @@

Warning: Plugins are an advanced, unstable feature! For many details, the only available documentation is the libsyntax and librustc API docs, or even the source +href="../syntax/index.html">libsyntax and librustc API docs, or even the source code itself. These internal compiler APIs are also subject to change at any time.

For defining new syntax it is often much easier to use Rust's built-in macro system. +href="macros.html">built-in macro system.

The code in this document uses language features not covered in the Rust -Guide. See the Reference Manual for more +Guide. See the Reference Manual for more information.

@@ -32,19 +32,19 @@ extend the compiler's behavior with new syntax extensions, lint checks, etc. A plugin is a dynamic library crate with a designated "registrar" function that registers extensions with `rustc`. Other crates can use these extensions by loading the plugin crate with `#[plugin] extern crate`. See the -[`rustc::plugin`](rustc/plugin/index.html) documentation for more about the +[`rustc::plugin`](../rustc/plugin/index.html) documentation for more about the mechanics of defining and loading a plugin. Arguments passed as `#[plugin=...]` or `#[plugin(...)]` are not interpreted by rustc itself. They are provided to the plugin through the `Registry`'s [`args` -method](rustc/plugin/registry/struct.Registry.html#method.args). +method](../rustc/plugin/registry/struct.Registry.html#method.args). # Syntax extensions Plugins can extend Rust's syntax in various ways. One kind of syntax extension is the procedural macro. These are invoked the same way as [ordinary -macros](guide-macros.html), but the expansion is performed by arbitrary Rust -code that manipulates [syntax trees](syntax/ast/index.html) at +macros](macros.html), but the expansion is performed by arbitrary Rust +code that manipulates [syntax trees](../syntax/ast/index.html) at compile time. Let's write a plugin @@ -126,14 +126,13 @@ The advantages over a simple `fn(&str) -> uint` are: a way to define new literal syntax for any data type. In addition to procedural macros, you can define new -[`deriving`](reference.html#deriving)-like attributes and other kinds of +[`deriving`](../reference.html#deriving)-like attributes and other kinds of extensions. See -[`Registry::register_syntax_extension`](rustc/plugin/registry/struct.Registry.html#method.register_syntax_extension) +[`Registry::register_syntax_extension`](../rustc/plugin/registry/struct.Registry.html#method.register_syntax_extension) and the [`SyntaxExtension` enum](http://doc.rust-lang.org/syntax/ext/base/enum.SyntaxExtension.html). For a more involved macro example, see -[`src/libregex_macros/lib.rs`](https://github.com/rust-lang/rust/blob/master/src/libregex_macros/lib.rs) -in the Rust distribution. +[`regex_macros`](https://github.com/rust-lang/regex/blob/master/regex_macros/src/lib.rs). ## Tips and tricks @@ -147,7 +146,7 @@ variables of the same name (but different syntax contexts) are in play in the same scope. In this case `--pretty expanded,hygiene` will tell you about the syntax contexts. -You can use [`syntax::parse`](syntax/parse/index.html) to turn token trees into +You can use [`syntax::parse`](../syntax/parse/index.html) to turn token trees into higher-level syntax elements like expressions: ```ignore @@ -163,23 +162,23 @@ Looking through [`libsyntax` parser code](https://github.com/rust-lang/rust/blob/master/src/libsyntax/parse/parser.rs) will give you a feel for how the parsing infrastructure works. -Keep the [`Span`s](syntax/codemap/struct.Span.html) of +Keep the [`Span`s](../syntax/codemap/struct.Span.html) of everything you parse, for better error reporting. You can wrap -[`Spanned`](syntax/codemap/struct.Spanned.html) around +[`Spanned`](../syntax/codemap/struct.Spanned.html) around your custom data structures. Calling -[`ExtCtxt::span_fatal`](syntax/ext/base/struct.ExtCtxt.html#method.span_fatal) +[`ExtCtxt::span_fatal`](../syntax/ext/base/struct.ExtCtxt.html#method.span_fatal) will immediately abort compilation. It's better to instead call -[`ExtCtxt::span_err`](syntax/ext/base/struct.ExtCtxt.html#method.span_err) +[`ExtCtxt::span_err`](../syntax/ext/base/struct.ExtCtxt.html#method.span_err) and return -[`DummyResult`](syntax/ext/base/struct.DummyResult.html), +[`DummyResult`](../syntax/ext/base/struct.DummyResult.html), so that the compiler can continue and find further errors. The example above produced an integer literal using -[`AstBuilder::expr_uint`](syntax/ext/build/trait.AstBuilder.html#tymethod.expr_uint). +[`AstBuilder::expr_uint`](../syntax/ext/build/trait.AstBuilder.html#tymethod.expr_uint). As an alternative to the `AstBuilder` trait, `libsyntax` provides a set of -[quasiquote macros](syntax/ext/quote/index.html). They are undocumented and +[quasiquote macros](../syntax/ext/quote/index.html). They are undocumented and very rough around the edges. However, the implementation may be a good starting point for an improved quasiquote as an ordinary plugin library. @@ -187,7 +186,7 @@ starting point for an improved quasiquote as an ordinary plugin library. # Lint plugins Plugins can extend [Rust's lint -infrastructure](reference.html#lint-check-attributes) with additional checks for +infrastructure](../reference.html#lint-check-attributes) with additional checks for code style, safety, etc. You can see [`src/test/auxiliary/lint_plugin_test.rs`](https://github.com/rust-lang/rust/blob/master/src/test/auxiliary/lint_plugin_test.rs) for a full example, the core of which is reproduced here: @@ -236,11 +235,11 @@ foo.rs:4 fn lintme() { } The components of a lint plugin are: * one or more `declare_lint!` invocations, which define static - [`Lint`](rustc/lint/struct.Lint.html) structs; + [`Lint`](../rustc/lint/struct.Lint.html) structs; * a struct holding any state needed by the lint pass (here, none); -* a [`LintPass`](rustc/lint/trait.LintPass.html) +* a [`LintPass`](../rustc/lint/trait.LintPass.html) implementation defining how to check each syntax element. A single `LintPass` may call `span_lint` for several different `Lint`s, but should register them all through the `get_lints` method. @@ -252,7 +251,7 @@ mostly use the same infrastructure as lint plugins, and provide examples of how to access type information. Lints defined by plugins are controlled by the usual [attributes and compiler -flags](reference.html#lint-check-attributes), e.g. `#[allow(test_lint)]` or +flags](../reference.html#lint-check-attributes), e.g. `#[allow(test_lint)]` or `-A test-lint`. These identifiers are derived from the first argument to `declare_lint!`, with appropriate case and punctuation conversion. diff --git a/src/doc/trpl/src/pointers.md b/src/doc/trpl/pointers.md similarity index 98% rename from src/doc/trpl/src/pointers.md rename to src/doc/trpl/pointers.md index 4c35fae3ecc..ad80d2812d0 100644 --- a/src/doc/trpl/src/pointers.md +++ b/src/doc/trpl/pointers.md @@ -409,7 +409,7 @@ test.rs:4 let y = &x; As you might guess, this kind of analysis is complex for a human, and therefore hard for a computer, too! There is an entire [guide devoted to references, ownership, -and lifetimes](guide-ownership.html) that goes into this topic in +and lifetimes](ownership.html) that goes into this topic in great detail, so if you want the full details, check that out. ## Best practices @@ -542,7 +542,7 @@ with some improvements: 4. Rust enforces that no other writeable pointers alias to this heap memory, which means writing to an invalid pointer is not possible. -See the section on references or the [ownership guide](guide-ownership.html) +See the section on references or the [ownership guide](ownership.html) for more detail on how lifetimes work. Using boxes and references together is very common. For example: @@ -780,6 +780,6 @@ Here's a quick rundown of Rust's pointer types: # Related resources -* [API documentation for Box](std/boxed/index.html) -* [Ownership guide](guide-ownership.html) +* [API documentation for Box](../std/boxed/index.html) +* [Ownership guide](ownership.html) * [Cyclone paper on regions](http://www.cs.umd.edu/projects/cyclone/papers/cyclone-regions.pdf), which inspired Rust's lifetime system diff --git a/src/doc/trpl/src/guide-lifetimes.md b/src/doc/trpl/src/guide-lifetimes.md deleted file mode 100644 index 7a5c535827c..00000000000 --- a/src/doc/trpl/src/guide-lifetimes.md +++ /dev/null @@ -1,565 +0,0 @@ -% The Rust References and Lifetimes Guide - -# Introduction - -References are one of the more flexible and powerful tools available in -Rust. They can point anywhere: into the heap, stack, and even into the -interior of another data structure. A reference is as flexible as a C pointer -or C++ reference. - -Unlike C and C++ compilers, the Rust compiler includes special static -checks that ensure that programs use references safely. - -Despite their complete safety, a reference's representation at runtime -is the same as that of an ordinary pointer in a C program. They introduce zero -overhead. The compiler does all safety checks at compile time. - -Although references have rather elaborate theoretical underpinnings -(e.g. region pointers), the core concepts will be familiar to anyone -who has worked with C or C++. The best way to explain how they are -used—and their limitations—is probably just to work through several examples. - -# By example - -References, sometimes known as *borrowed pointers*, are only valid for -a limited duration. References never claim any kind of ownership -over the data that they point to. Instead, they are used for cases -where you would like to use data for a short time. - -Consider a simple struct type `Point`: - -~~~ -struct Point {x: f64, y: f64} -~~~ - -We can use this simple definition to allocate points in many different ways. For -example, in this code, each of these local variables contains a point, -but allocated in a different place: - -~~~ -# struct Point {x: f64, y: f64} -let on_the_stack : Point = Point {x: 3.0, y: 4.0}; -let on_the_heap : Box = box Point {x: 7.0, y: 9.0}; -~~~ - -Suppose we wanted to write a procedure that computed the distance between any -two points, no matter where they were stored. One option is to define a function -that takes two arguments of type `Point`—that is, it takes the points by value. -But if we define it this way, calling the function will cause the points to be -copied. For points, this is probably not so bad, but often copies are -expensive. So we'd like to define a function that takes the points just as -a reference. - -~~~ -# use std::num::Float; -# struct Point {x: f64, y: f64} -# fn sqrt(f: f64) -> f64 { 0.0 } -fn compute_distance(p1: &Point, p2: &Point) -> f64 { - let x_d = p1.x - p2.x; - let y_d = p1.y - p2.y; - (x_d * x_d + y_d * y_d).sqrt() -} -~~~ - -Now we can call `compute_distance()`: - -~~~ -# struct Point {x: f64, y: f64} -# let on_the_stack : Point = Point{x: 3.0, y: 4.0}; -# let on_the_heap : Box = box Point{x: 7.0, y: 9.0}; -# fn compute_distance(p1: &Point, p2: &Point) -> f64 { 0.0 } -compute_distance(&on_the_stack, &*on_the_heap); -~~~ - -Here, the `&` operator takes the address of the variable -`on_the_stack`; this is because `on_the_stack` has the type `Point` -(that is, a struct value) and we have to take its address to get a -value. We also call this _borrowing_ the local variable -`on_the_stack`, because we have created an alias: that is, another -name for the same data. - -Likewise, in the case of `on_the_heap`, -the `&` operator is used in conjunction with the `*` operator -to take a reference to the contents of the box. - -Whenever a caller lends data to a callee, there are some limitations on what -the caller can do with the original. For example, if the contents of a -variable have been lent out, you cannot send that variable to another task. In -addition, the compiler will reject any code that might cause the borrowed -value to be freed or overwrite its component fields with values of different -types (I'll get into what kinds of actions those are shortly). This rule -should make intuitive sense: you must wait for a borrower to return the value -that you lent it (that is, wait for the reference to go out of scope) -before you can make full use of it again. - -# Other uses for the & operator - -In the previous example, the value `on_the_stack` was defined like so: - -~~~ -# struct Point {x: f64, y: f64} -let on_the_stack: Point = Point {x: 3.0, y: 4.0}; -~~~ - -This declaration means that code can only pass `Point` by value to other -functions. As a consequence, we had to explicitly take the address of -`on_the_stack` to get a reference. Sometimes however it is more -convenient to move the & operator into the definition of `on_the_stack`: - -~~~ -# struct Point {x: f64, y: f64} -let on_the_stack2: &Point = &Point {x: 3.0, y: 4.0}; -~~~ - -Applying `&` to an rvalue (non-assignable location) is just a convenient -shorthand for creating a temporary and taking its address. A more verbose -way to write the same code is: - -~~~ -# struct Point {x: f64, y: f64} -let tmp = Point {x: 3.0, y: 4.0}; -let on_the_stack2 : &Point = &tmp; -~~~ - -# Taking the address of fields - -The `&` operator is not limited to taking the address of -local variables. It can also take the address of fields or -individual array elements. For example, consider this type definition -for `Rectangle`: - -~~~ -struct Point {x: f64, y: f64} // as before -struct Size {w: f64, h: f64} // as before -struct Rectangle {origin: Point, size: Size} -~~~ - -Now, as before, we can define rectangles in a few different ways: - -~~~ -# struct Point {x: f64, y: f64} -# struct Size {w: f64, h: f64} // as before -# struct Rectangle {origin: Point, size: Size} -let rect_stack = &Rectangle {origin: Point {x: 1.0, y: 2.0}, - size: Size {w: 3.0, h: 4.0}}; -let rect_heap = box Rectangle {origin: Point {x: 5.0, y: 6.0}, - size: Size {w: 3.0, h: 4.0}}; -~~~ - -In each case, we can extract out individual subcomponents with the `&` -operator. For example, I could write: - -~~~ -# struct Point {x: f64, y: f64} // as before -# struct Size {w: f64, h: f64} // as before -# struct Rectangle {origin: Point, size: Size} -# let rect_stack = &Rectangle {origin: Point {x: 1.0, y: 2.0}, size: Size {w: 3.0, h: 4.0}}; -# let rect_heap = box Rectangle {origin: Point {x: 5.0, y: 6.0}, size: Size {w: 3.0, h: 4.0}}; -# fn compute_distance(p1: &Point, p2: &Point) -> f64 { 0.0 } -compute_distance(&rect_stack.origin, &rect_heap.origin); -~~~ - -which would borrow the field `origin` from the rectangle on the stack -as well as from the owned box, and then compute the distance between them. - -# Lifetimes - -We’ve seen a few examples of borrowing data. To this point, we’ve glossed -over issues of safety. As stated in the introduction, at runtime a reference -is simply a pointer, nothing more. Therefore, avoiding C's problems with -dangling pointers requires a compile-time safety check. - -The basis for the check is the notion of _lifetimes_. A lifetime is a -static approximation of the span of execution during which the pointer -is valid: it always corresponds to some expression or block within the -program. - -The compiler will only allow a borrow *if it can guarantee that the data will -not be reassigned or moved for the lifetime of the pointer*. This does not -necessarily mean that the data is stored in immutable memory. For example, -the following function is legal: - -~~~ -# fn some_condition() -> bool { true } -# struct Foo { f: int } -fn example3() -> int { - let mut x = box Foo {f: 3}; - if some_condition() { - let y = &x.f; // -+ L - return *y; // | - } // -+ - x = box Foo {f: 4}; - // ... -# return 0; -} -~~~ - -Here, the interior of the variable `x` is being borrowed -and `x` is declared as mutable. However, the compiler can prove that -`x` is not assigned anywhere in the lifetime L of the variable -`y`. Therefore, it accepts the function, even though `x` is mutable -and in fact is mutated later in the function. - -It may not be clear why we are so concerned about mutating a borrowed -variable. The reason is that the runtime system frees any box -_as soon as its owning reference changes or goes out of -scope_. Therefore, a program like this is illegal (and would be -rejected by the compiler): - -~~~ {.ignore} -fn example3() -> int { - let mut x = box X {f: 3}; - let y = &x.f; - x = box X {f: 4}; // Error reported here. - *y -} -~~~ - -To make this clearer, consider this diagram showing the state of -memory immediately before the re-assignment of `x`: - -~~~ {.text} - Stack Exchange Heap - - x +-------------+ - | box {f:int} | ----+ - y +-------------+ | - | &int | ----+ - +-------------+ | +---------+ - +--> | f: 3 | - +---------+ -~~~ - -Once the reassignment occurs, the memory will look like this: - -~~~ {.text} - Stack Exchange Heap - - x +-------------+ +---------+ - | box {f:int} | -------> | f: 4 | - y +-------------+ +---------+ - | &int | ----+ - +-------------+ | +---------+ - +--> | (freed) | - +---------+ -~~~ - -Here you can see that the variable `y` still points at the old `f` -property of Foo, which has been freed. - -In fact, the compiler can apply the same kind of reasoning to any -memory that is (uniquely) owned by the stack frame. So we could -modify the previous example to introduce additional owned pointers -and structs, and the compiler will still be able to detect possible -mutations. This time, we'll use an analogy to illustrate the concept. - -~~~ {.ignore} -fn example3() -> int { - struct House { owner: Box } - struct Person { age: int } - - let mut house = box House { - owner: box Person {age: 30} - }; - - let owner_age = &house.owner.age; - house = box House {owner: box Person {age: 40}}; // Error reported here. - house.owner = box Person {age: 50}; // Error reported here. - *owner_age -} -~~~ - -In this case, two errors are reported, one when the variable `house` is -modified and another when `house.owner` is modified. Either modification would -invalidate the pointer `owner_age`. - -# Borrowing and enums - -The previous example showed that the type system forbids any mutations -of owned boxed values while they are being borrowed. In general, the type -system also forbids borrowing a value as mutable if it is already being -borrowed - either as a mutable reference or an immutable one. This restriction -prevents pointers from pointing into freed memory. There is one other -case where the compiler must be very careful to ensure that pointers -remain valid: pointers into the interior of an `enum`. - -Let’s look at the following `shape` type that can represent both rectangles -and circles: - -~~~ -struct Point {x: f64, y: f64}; // as before -struct Size {w: f64, h: f64}; // as before -enum Shape { - Circle(Point, f64), // origin, radius - Rectangle(Point, Size) // upper-left, dimensions -} -~~~ - -Now we might write a function to compute the area of a shape. This -function takes a reference to a shape, to avoid the need for -copying. - -~~~ -# struct Point {x: f64, y: f64}; // as before -# struct Size {w: f64, h: f64}; // as before -# enum Shape { -# Circle(Point, f64), // origin, radius -# Rectangle(Point, Size) // upper-left, dimensions -# } -fn compute_area(shape: &Shape) -> f64 { - match *shape { - Shape::Circle(_, radius) => std::f64::consts::PI * radius * radius, - Shape::Rectangle(_, ref size) => size.w * size.h - } -} -~~~ - -The first case matches against circles. Here, the pattern extracts the -radius from the shape variant and the action uses it to compute the -area of the circle. - -The second match is more interesting. Here we match against a -rectangle and extract its size: but rather than copy the `size` -struct, we use a by-reference binding to create a pointer to it. In -other words, a pattern binding like `ref size` binds the name `size` -to a pointer of type `&size` into the _interior of the enum_. - -To make this more clear, let's look at a diagram of memory layout in -the case where `shape` points at a rectangle: - -~~~ {.text} -Stack Memory - -+-------+ +---------------+ -| shape | ------> | rectangle( | -+-------+ | {x: f64, | -| size | -+ | y: f64}, | -+-------+ +----> | {w: f64, | - | h: f64}) | - +---------------+ -~~~ - -Here you can see that rectangular shapes are composed of five words of -memory. The first is a tag indicating which variant this enum is -(`rectangle`, in this case). The next two words are the `x` and `y` -fields for the point and the remaining two are the `w` and `h` fields -for the size. The binding `size` is then a pointer into the inside of -the shape. - -Perhaps you can see where the danger lies: if the shape were somehow -to be reassigned, perhaps to a circle, then although the memory used -to store that shape value would still be valid, _it would have a -different type_! The following diagram shows what memory would look -like if code overwrote `shape` with a circle: - -~~~ {.text} -Stack Memory - -+-------+ +---------------+ -| shape | ------> | circle( | -+-------+ | {x: f64, | -| size | -+ | y: f64}, | -+-------+ +----> | f64) | - | | - +---------------+ -~~~ - -As you can see, the `size` pointer would be pointing at a `f64` -instead of a struct. This is not good: dereferencing the second field -of a `f64` as if it were a struct with two fields would be a memory -safety violation. - -So, in fact, for every `ref` binding, the compiler will impose the -same rules as the ones we saw for borrowing the interior of an owned -box: it must be able to guarantee that the `enum` will not be -overwritten for the duration of the borrow. In fact, the compiler -would accept the example we gave earlier. The example is safe because -the shape pointer has type `&Shape`, which means "reference to -immutable memory containing a `shape`". If, however, the type of that -pointer were `&mut Shape`, then the ref binding would be ill-typed. -Just as with owned boxes, the compiler will permit `ref` bindings -into data owned by the stack frame even if the data are mutable, -but otherwise it requires that the data reside in immutable memory. - -# Returning references - -So far, all of the examples we have looked at, use references in a -“downward” direction. That is, a method or code block creates a -reference, then uses it within the same scope. It is also -possible to return references as the result of a function, but -as we'll see, doing so requires some explicit annotation. - -We could write a subroutine like this: - -~~~ -struct Point {x: f64, y: f64} -fn get_x<'r>(p: &'r Point) -> &'r f64 { &p.x } -~~~ - -Here, the function `get_x()` returns a pointer into the structure it -was given. The type of the parameter (`&'r Point`) and return type -(`&'r f64`) both use a new syntactic form that we have not seen so -far. Here the identifier `r` names the lifetime of the pointer -explicitly. So in effect, this function declares that it takes a -pointer with lifetime `r` and returns a pointer with that same -lifetime. - -In general, it is only possible to return references if they -are derived from a parameter to the procedure. In that case, the -pointer result will always have the same lifetime as one of the -parameters; named lifetimes indicate which parameter that -is. - -In the previous code samples, function parameter types did not include a -lifetime name. The compiler simply creates a fresh name for the lifetime -automatically: that is, the lifetime name is guaranteed to refer to a distinct -lifetime from the lifetimes of all other parameters. - -Named lifetimes that appear in function signatures are conceptually -the same as the other lifetimes we have seen before, but they are a bit -abstract: they don’t refer to a specific expression within `get_x()`, -but rather to some expression within the *caller of `get_x()`*. The -lifetime `r` is actually a kind of *lifetime parameter*: it is defined -by the caller to `get_x()`, just as the value for the parameter `p` is -defined by that caller. - -In any case, whatever the lifetime of `r` is, the pointer produced by -`&p.x` always has the same lifetime as `p` itself: a pointer to a -field of a struct is valid as long as the struct is valid. Therefore, -the compiler accepts the function `get_x()`. - -In general, if you borrow a struct or box to create a -reference, it will only be valid within the function -and cannot be returned. This is why the typical way to return references -is to take references as input (the only other case in -which it can be legal to return a reference is if it -points at a static constant). - -# Named lifetimes - -Lifetimes can be named and referenced. For example, the special lifetime -`'static`, which does not go out of scope, can be used to create global -variables and communicate between tasks (see the manual for use cases). - -## Parameter Lifetimes - -Named lifetimes allow for grouping of parameters by lifetime. -For example, consider this function: - -~~~ -# struct Point {x: f64, y: f64}; // as before -# struct Size {w: f64, h: f64}; // as before -# enum Shape { -# Circle(Point, f64), // origin, radius -# Rectangle(Point, Size) // upper-left, dimensions -# } -# fn compute_area(shape: &Shape) -> f64 { 0.0 } -fn select<'r, T>(shape: &'r Shape, threshold: f64, - a: &'r T, b: &'r T) -> &'r T { - if compute_area(shape) > threshold {a} else {b} -} -~~~ - -This function takes three references and assigns each the same -lifetime `r`. In practice, this means that, in the caller, the -lifetime `r` will be the *intersection of the lifetime of the three -region parameters*. This may be overly conservative, as in this -example: - -~~~ -# struct Point {x: f64, y: f64}; // as before -# struct Size {w: f64, h: f64}; // as before -# enum Shape { -# Circle(Point, f64), // origin, radius -# Rectangle(Point, Size) // upper-left, dimensions -# } -# fn compute_area(shape: &Shape) -> f64 { 0.0 } -# fn select<'r, T>(shape: &Shape, threshold: f64, -# a: &'r T, b: &'r T) -> &'r T { -# if compute_area(shape) > threshold {a} else {b} -# } - // -+ r -fn select_based_on_unit_circle<'r, T>( // |-+ B - threshold: f64, a: &'r T, b: &'r T) -> &'r T { // | | - // | | - let shape = Shape::Circle(Point {x: 0., y: 0.}, 1.); // | | - select(&shape, threshold, a, b) // | | -} // |-+ - // -+ -~~~ - -In this call to `select()`, the lifetime of the first parameter shape -is B, the function body. Both of the second two parameters `a` and `b` -share the same lifetime, `r`, which is a lifetime parameter of -`select_based_on_unit_circle()`. The caller will infer the -intersection of these two lifetimes as the lifetime of the returned -value, and hence the return value of `select()` will be assigned a -lifetime of B. This will in turn lead to a compilation error, because -`select_based_on_unit_circle()` is supposed to return a value with the -lifetime `r`. - -To address this, we can modify the definition of `select()` to -distinguish the lifetime of the first parameter from the lifetime of -the latter two. After all, the first parameter is not being -returned. Here is how the new `select()` might look: - -~~~ -# struct Point {x: f64, y: f64}; // as before -# struct Size {w: f64, h: f64}; // as before -# enum Shape { -# Circle(Point, f64), // origin, radius -# Rectangle(Point, Size) // upper-left, dimensions -# } -# fn compute_area(shape: &Shape) -> f64 { 0.0 } -fn select<'r, 'tmp, T>(shape: &'tmp Shape, threshold: f64, - a: &'r T, b: &'r T) -> &'r T { - if compute_area(shape) > threshold {a} else {b} -} -~~~ - -Here you can see that `shape`'s lifetime is now named `tmp`. The -parameters `a`, `b`, and the return value all have the lifetime `r`. -However, since the lifetime `tmp` is not returned, it would be more -concise to just omit the named lifetime for `shape` altogether: - -~~~ -# struct Point {x: f64, y: f64}; // as before -# struct Size {w: f64, h: f64}; // as before -# enum Shape { -# Circle(Point, f64), // origin, radius -# Rectangle(Point, Size) // upper-left, dimensions -# } -# fn compute_area(shape: &Shape) -> f64 { 0.0 } -fn select<'r, T>(shape: &Shape, threshold: f64, - a: &'r T, b: &'r T) -> &'r T { - if compute_area(shape) > threshold {a} else {b} -} -~~~ - -This is equivalent to the previous definition. - -## Labeled Control Structures - -Named lifetime notation can also be used to control the flow of execution: - -~~~ -'h: for i in range(0u, 10) { - 'g: loop { - if i % 2 == 0 { continue 'h; } - if i == 9 { break 'h; } - break 'g; - } -} -~~~ - -> *Note:* Labelled breaks are not currently supported within `while` loops. - -Named labels are hygienic and can be used safely within macros. -See the macros guide section on hygiene for more details. - -# Conclusion - -So there you have it: a (relatively) brief tour of the lifetime -system. For more details, we refer to the (yet to be written) reference -document on references, which will explain the full notation -and give more examples. diff --git a/src/doc/trpl/src/standard-input.md b/src/doc/trpl/standard-input.md similarity index 99% rename from src/doc/trpl/src/standard-input.md rename to src/doc/trpl/standard-input.md index 5a150594f0c..2d31f06ebaa 100644 --- a/src/doc/trpl/src/standard-input.md +++ b/src/doc/trpl/standard-input.md @@ -1,4 +1,4 @@ -# Standard Input +% Standard Input Getting input from the keyboard is pretty easy, but uses some things we haven't seen before. Here's a simple program that reads some input, diff --git a/src/doc/trpl/src/strings.md b/src/doc/trpl/strings.md similarity index 99% rename from src/doc/trpl/src/strings.md rename to src/doc/trpl/strings.md index be1d09f6e95..a40e748dae7 100644 --- a/src/doc/trpl/src/strings.md +++ b/src/doc/trpl/strings.md @@ -1,4 +1,4 @@ -# Strings +% Strings Strings are an important concept for any programmer to master. Rust's string handling system is a bit different from other languages, due to its systems diff --git a/src/doc/trpl/src/tasks.md b/src/doc/trpl/tasks.md similarity index 99% rename from src/doc/trpl/src/tasks.md rename to src/doc/trpl/tasks.md index 8eb13187e58..8e9f40b0f4e 100644 --- a/src/doc/trpl/src/tasks.md +++ b/src/doc/trpl/tasks.md @@ -369,7 +369,7 @@ Unlike `spawn`, the function spawned using `try` may return a value, which child thread terminates successfully, `try` will return an `Ok` result; if the child thread panics, `try` will return an `Error` result. -[`Result`]: std/result/index.html +[`Result`]: ../std/result/index.html > *Note:* A panicked thread does not currently produce a useful error > value (`try` always returns `Err(())`). In the diff --git a/src/doc/trpl/src/testing.md b/src/doc/trpl/testing.md similarity index 100% rename from src/doc/trpl/src/testing.md rename to src/doc/trpl/testing.md diff --git a/src/doc/trpl/src/traits.md b/src/doc/trpl/traits.md similarity index 100% rename from src/doc/trpl/src/traits.md rename to src/doc/trpl/traits.md diff --git a/src/doc/trpl/src/unsafe.md b/src/doc/trpl/unsafe.md similarity index 98% rename from src/doc/trpl/src/unsafe.md rename to src/doc/trpl/unsafe.md index 25ca07ad74f..3e0a1ef1345 100644 --- a/src/doc/trpl/src/unsafe.md +++ b/src/doc/trpl/unsafe.md @@ -12,7 +12,7 @@ block which allows the programmer to dodge some of the compiler's checks and do a wide range of operations, such as: - dereferencing [raw pointers](#raw-pointers) -- calling a function via FFI ([covered by the FFI guide](guide-ffi.html)) +- calling a function via FFI ([covered by the FFI guide](ffi.html)) - casting between types bitwise (`transmute`, aka "reinterpret cast") - [inline assembly](#inline-assembly) @@ -37,7 +37,7 @@ build safe interfaces. ## References One of Rust's biggest features is memory safety. This is achieved in -part via [the ownership system](guide-ownership.html), which is how the +part via [the ownership system](ownership.html), which is how the compiler can guarantee that every `&` reference is always valid, and, for example, never pointing to freed memory. @@ -504,7 +504,7 @@ shouldn't get triggered. The second of these three functions, `eh_personality`, is used by the failure mechanisms of the compiler. This is often mapped to GCC's personality function (see the -[libstd implementation](std/rt/unwind/index.html) for more +[libstd implementation](../std/rt/unwind/index.html) for more information), but crates which do not trigger a panic can be assured that this function is never called. The final function, `panic_fmt`, is also used by the failure mechanisms of the compiler. @@ -517,7 +517,7 @@ also used by the failure mechanisms of the compiler. With the above techniques, we've got a bare-metal executable running some Rust code. There is a good deal of functionality provided by the standard library, however, that is necessary to be productive in Rust. If the standard library is -not sufficient, then [libcore](core/index.html) is designed to be used +not sufficient, then [libcore](../core/index.html) is designed to be used instead. The core library has very few dependencies and is much more portable than the diff --git a/src/doc/trpl/src/variable-bindings.md b/src/doc/trpl/variable-bindings.md similarity index 98% rename from src/doc/trpl/src/variable-bindings.md rename to src/doc/trpl/variable-bindings.md index 8cf2522b9af..4e2e7bd2fe2 100644 --- a/src/doc/trpl/src/variable-bindings.md +++ b/src/doc/trpl/variable-bindings.md @@ -1,4 +1,4 @@ -# Variable bindings +% Variable bindings The first thing we'll learn about are 'variable bindings.' They look like this: @@ -170,5 +170,5 @@ arguments we pass to functions and macros, if you're passing more than one. When you just use the curly braces, Rust will attempt to display the value in a meaningful way by checking out its type. If you want to specify the format in a more detailed manner, there are a [wide number of options -available](std/fmt/index.html). For now, we'll just stick to the default: +available](../std/fmt/index.html). For now, we'll just stick to the default: integers aren't very complicated to print. diff --git a/src/rustbook/book.rs b/src/rustbook/book.rs index 45a864e3378..1d16de2a2fe 100644 --- a/src/rustbook/book.rs +++ b/src/rustbook/book.rs @@ -29,8 +29,8 @@ pub struct Book { /// A depth-first iterator over a book. pub struct BookItems<'a> { cur_items: &'a [BookItem], - cur_idx: uint, - stack: Vec<(&'a [BookItem], uint)>, + cur_idx: usize, + stack: Vec<(&'a [BookItem], usize)>, } impl<'a> Iterator for BookItems<'a> { @@ -80,7 +80,7 @@ impl Book { pub fn parse_summary(input: R, src: &Path) -> Result> { fn collapse(stack: &mut Vec, top_items: &mut Vec, - to_level: uint) { + to_level: usize) { loop { if stack.len() < to_level { return } if stack.len() == 1 { @@ -141,7 +141,7 @@ pub fn parse_summary(input: R, src: &Path) -> Result 1u, + ' ' => 1us, '\t' => 4, _ => unreachable!() } diff --git a/src/rustbook/build.rs b/src/rustbook/build.rs old mode 100755 new mode 100644 index db79e0b45e0..1cb5e38e190 --- a/src/rustbook/build.rs +++ b/src/rustbook/build.rs @@ -130,8 +130,8 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> { ]; let output_result = rustdoc::main_args(rustdoc_args); if output_result != 0 { - - let message = format!("Could not execute `rustdoc`: {}", output_result); + let message = format!("Could not execute `rustdoc` with {:?}: {}", + rustdoc_args, output_result); return Err(box message as Box); } } @@ -172,12 +172,13 @@ impl Subcommand for Build { match book::parse_summary(summary, &src) { Ok(book) => { // execute rustdoc on the whole book - let _ = render(&book, &tgt).map_err(|err| { + try!(render(&book, &tgt).map_err(|err| { term.err(&format!("error: {}", err.description())[]); err.detail().map(|detail| { term.err(&format!("detail: {}", detail)[]); - }) - }); + }); + err + })) } Err(errors) => { for err in errors.into_iter() { diff --git a/src/rustbook/error.rs b/src/rustbook/error.rs index 1d3baef8c1c..a5915ed4d73 100644 --- a/src/rustbook/error.rs +++ b/src/rustbook/error.rs @@ -56,6 +56,12 @@ impl Error for String { } } +impl<'a> Error for Box { + fn description(&self) -> &str { (**self).description() } + fn detail(&self) -> Option<&str> { (**self).detail() } + fn cause(&self) -> Option<&Error> { (**self).cause() } +} + impl FromError<()> for () { fn from_err(_: ()) -> () { () } } diff --git a/src/rustbook/main.rs b/src/rustbook/main.rs old mode 100755 new mode 100644 diff --git a/src/rustbook/term.rs b/src/rustbook/term.rs index 18306d6ec20..471e22ce7c1 100644 --- a/src/rustbook/term.rs +++ b/src/rustbook/term.rs @@ -11,6 +11,7 @@ //! An abstraction of the terminal. Eventually, provide color and //! verbosity support. For now, just a wrapper around stdout/stderr. +use std::os; use std::io::stdio; pub struct Term { @@ -27,5 +28,6 @@ impl Term { pub fn err(&mut self, msg: &str) { // swallow any errors let _ = self.err.write_line(msg); + os::set_exit_status(101); } }