diff --git a/src/Cargo.lock b/src/Cargo.lock index da9190b32c2..f17095f9609 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -270,7 +270,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "mdbook" -version = "0.0.15" +version = "0.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -401,7 +401,7 @@ name = "rustbook" version = "0.1.0" dependencies = [ "clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)", - "mdbook 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)", + "mdbook 0.0.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -991,7 +991,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6abe0ee2e758cd6bc8a2cd56726359007748fbf4128da998b65d0b70f881e19b" "checksum libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "684f330624d8c3784fb9558ca46c4ce488073a8d22450415c5eb4f4cfb0d11b5" "checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054" -"checksum mdbook 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "9a6b8e6eb10d1c6beeca799fe5919778cf5c6f22a4f2abb5f50faea1221adeae" +"checksum mdbook 0.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "14e8a6aca534ac51bad1c1886b10f6d6948a14fa70b1b20a1e41c9e5c0fe3019" "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4" "checksum num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "a16a42856a256b39c6d3484f097f6713e14feacd9bfb02290917904fae46c81c" "checksum num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "cee7e88156f3f9e19bdd598f8d6c9db7bf4078f99f8381f43a55b09648d1a6e3" diff --git a/src/doc/book/src/casting-between-types.md b/src/doc/book/src/casting-between-types.md index 2f6730be665..853fb1ec254 100644 --- a/src/doc/book/src/casting-between-types.md +++ b/src/doc/book/src/casting-between-types.md @@ -8,7 +8,7 @@ most dangerous features of Rust! # Coercion Coercion between types is implicit and has no syntax of its own, but can -be spelled out with [`as`](#Explicit%20coercions). +be spelled out with [`as`](#explicit-coercions). Coercion occurs in `let`, `const`, and `static` statements; in function call arguments; in field values in struct initialization; and in a diff --git a/src/doc/book/src/closures.md b/src/doc/book/src/closures.md index 2f6d5039f4d..5426ed0ff4c 100644 --- a/src/doc/book/src/closures.md +++ b/src/doc/book/src/closures.md @@ -463,7 +463,7 @@ fn factory() -> &(Fn(i32) -> i32) { Right. Because we have a reference, we need to give it a lifetime. But our `factory()` function takes no arguments, so -[elision](lifetimes.html#Lifetime%20Elision) doesn’t kick in here. Then what +[elision](lifetimes.html#lifetime-elision) doesn’t kick in here. Then what choices do we have? Try `'static`: ```rust,ignore diff --git a/src/doc/book/src/compiler-plugins.md b/src/doc/book/src/compiler-plugins.md index 47c5e5c8291..1b7ce678982 100644 --- a/src/doc/book/src/compiler-plugins.md +++ b/src/doc/book/src/compiler-plugins.md @@ -127,7 +127,7 @@ enum. For a more involved macro example, see ## Tips and tricks -Some of the [macro debugging tips](macros.html#Debugging%20macro%20code) are applicable. +Some of the [macro debugging tips](macros.html#debugging-macro-code) are applicable. You can use `syntax::parse` to turn token trees into higher-level syntax elements like expressions: diff --git a/src/doc/book/src/concurrency.md b/src/doc/book/src/concurrency.md index e5bc7ecdd0b..a64178c26f2 100644 --- a/src/doc/book/src/concurrency.md +++ b/src/doc/book/src/concurrency.md @@ -55,7 +55,7 @@ For sharing references across threads, Rust provides a wrapper type called `Arc`. `Arc` implements `Send` and `Sync` if and only if `T` implements both `Send` and `Sync`. For example, an object of type `Arc>` cannot be transferred across threads because -[`RefCell`](choosing-your-guarantees.html#RefCell%3CT%3E) does not implement +[`RefCell`](choosing-your-guarantees.html#refcellt) does not implement `Sync`, consequently `Arc>` would not implement `Send`. These two traits allow you to use the type system to make strong guarantees @@ -126,7 +126,7 @@ closure only captures a _reference to `x`_. This is a problem, because the thread may outlive the scope of `x`, leading to a dangling pointer. To fix this, we use a `move` closure as mentioned in the error message. `move` -closures are explained in depth [here](closures.html#move%20closures); basically +closures are explained in depth [here](closures.html#move-closures); basically they move variables from their environment into themselves. ```rust diff --git a/src/doc/book/src/error-handling.md b/src/doc/book/src/error-handling.md index 1b0d2453275..c823c32a135 100644 --- a/src/doc/book/src/error-handling.md +++ b/src/doc/book/src/error-handling.md @@ -21,35 +21,35 @@ sum types and combinators, and try to motivate the way Rust does error handling incrementally. As such, programmers with experience in other expressive type systems may want to jump around. -* [The Basics](#The%20Basics) - * [Unwrapping explained](#Unwrapping%20explained) - * [The `Option` type](#The%20Option%20type) - * [Composing `Option` values](#Composing%20Option%3CT%3E%20values) - * [The `Result` type](#The%20Result%20type) - * [Parsing integers](#Parsing%20integers) - * [The `Result` type alias idiom](#The%20Result%20type%20alias%20idiom) - * [A brief interlude: unwrapping isn't evil](#A%20brief%20interlude:%20unwrapping%20isnt%20evil) -* [Working with multiple error types](#Working%20with%20multiple%20error%20types) - * [Composing `Option` and `Result`](#Composing%20Option%20and%20Result) - * [The limits of combinators](#The%20limits%20of%20combinators) - * [Early returns](#Early%20returns) - * [The `try!` macro](#The%20try%20macro) - * [Defining your own error type](#Defining%20your%20own%20error%20type) -* [Standard library traits used for error handling](#Standard%20library%20traits%20used%20for%20error%20handling) - * [The `Error` trait](#The%20Error%20trait) - * [The `From` trait](#The%20From%20trait) - * [The real `try!` macro](#The%20real%20try%20macro) - * [Composing custom error types](#Composing%20custom%20error%20types) - * [Advice for library writers](#Advice%20for%20library%20writers) -* [Case study: A program to read population data](#Case%20study:%20A%20program%20to%20read%20population%20data) - * [Initial setup](#Initial%20setup) - * [Argument parsing](#Argument%20parsing) - * [Writing the logic](#Writing%20the%20logic) - * [Error handling with `Box`](#Error%20handling%20with%20Box%3CError%3E) - * [Reading from stdin](#Reading%20from%20stdin) - * [Error handling with a custom type](#Error%20handling%20with%20a%20custom%20type) - * [Adding functionality](#Adding%20functionality) -* [The short story](#The%20short%20story) +* [The Basics](#the-basics) + * [Unwrapping explained](#unwrapping-explained) + * [The `Option` type](#the-option-type) + * [Composing `Option` values](#composing-optiont-values) + * [The `Result` type](#the-result-type) + * [Parsing integers](#parsing-integers) + * [The `Result` type alias idiom](#the-result-type-alias-idiom) + * [A brief interlude: unwrapping isn't evil](#a-brief-interlude-unwrapping-isnt-evil) +* [Working with multiple error types](#working-with-multiple-error-types) + * [Composing `Option` and `Result`](#composing-option-and-result) + * [The limits of combinators](#the-limits-of-combinators) + * [Early returns](#early-returns) + * [The `try!` macro](#the-try-macro) + * [Defining your own error type](#defining-your-own-error-type) +* [Standard library traits used for error handling](#standard-library-traits-used-for-error-handling) + * [The `Error` trait](#the-error-trait) + * [The `From` trait](#the-from-trait) + * [The real `try!` macro](#the-real-try-macro) + * [Composing custom error types](#composing-custom-error-types) + * [Advice for library writers](#advice-for-library-writers) +* [Case study: A program to read population data](#case-study-a-program-to-read-population-data) + * [Initial setup](#initial-setup) + * [Argument parsing](#argument-parsing) + * [Writing the logic](#writing-the-logic) + * [Error handling with `Box`](#error-handling-with-boxerror) + * [Reading from stdin](#reading-from-stdin) + * [Error handling with a custom type](#error-handling-with-a-custom-type) + * [Adding functionality](#adding-functionality) +* [The short story](#the-short-story) # The Basics @@ -796,7 +796,7 @@ because of the return types of [`std::fs::File::open`](../std/fs/struct.File.html#method.open) and [`std::io::Read::read_to_string`](../std/io/trait.Read.html#method.read_to_string). (Note that they both use the [`Result` type alias -idiom](#The%20Result%20type%20alias%20idiom) described previously. If you +idiom](#the-result-type-alias-idiom) described previously. If you click on the `Result` type, you'll [see the type alias](../std/io/type.Result.html), and consequently, the underlying `io::Error` type.) The third problem is described by the @@ -1120,7 +1120,7 @@ returns an `&Error`, which is itself a trait object. We'll revisit the For now, it suffices to show an example implementing the `Error` trait. Let's use the error type we defined in the -[previous section](#Defining%20your%20own%20error%20type): +[previous section](#defining-your-own-error-type): ```rust use std::io; @@ -1493,19 +1493,19 @@ representation. But certainly, this will vary depending on use cases. At a minimum, you should probably implement the [`Error`](../std/error/trait.Error.html) trait. This will give users of your library some minimum flexibility for -[composing errors](#The%20real%20try%20macro). Implementing the `Error` trait also +[composing errors](#the-real-try-macro). Implementing the `Error` trait also means that users are guaranteed the ability to obtain a string representation of an error (because it requires impls for both `fmt::Debug` and `fmt::Display`). Beyond that, it can also be useful to provide implementations of `From` on your error types. This allows you (the library author) and your users to -[compose more detailed errors](#Composing%20custom%20error%20types). For example, +[compose more detailed errors](#composing-custom-error-types). For example, [`csv::Error`](http://burntsushi.net/rustdoc/csv/enum.Error.html) provides `From` impls for both `io::Error` and `byteorder::Error`. Finally, depending on your tastes, you may also want to define a -[`Result` type alias](#The%20Result%20type%20alias%20idiom), particularly if your +[`Result` type alias](#the-result-type-alias-idiom), particularly if your library defines a single error type. This is used in the standard library for [`io::Result`](../std/io/type.Result.html) and [`fmt::Result`](../std/fmt/type.Result.html). @@ -1538,7 +1538,7 @@ and [`rustc-serialize`](https://crates.io/crates/rustc-serialize) crates. We're not going to spend a lot of time on setting up a project with Cargo because it is already covered well in [the Cargo -section](getting-started.html#Hello%20Cargo) and [Cargo's documentation][14]. +section](getting-started.html#hello-cargo) and [Cargo's documentation][14]. To get started from scratch, run `cargo new --bin city-pop` and make sure your `Cargo.toml` looks something like this: @@ -1729,7 +1729,7 @@ error types and you don't need any `From` implementations. The downside is that since `Box` is a trait object, it *erases the type*, which means the compiler can no longer reason about its underlying type. -[Previously](#The%20limits%20of%20combinators) we started refactoring our code by +[Previously](#the-limits-of-combinators) we started refactoring our code by changing the type of our function from `T` to `Result`. In this case, `OurErrorType` is only `Box`. But what's `T`? And can we add a return type to `main`? diff --git a/src/doc/book/src/ffi.md b/src/doc/book/src/ffi.md index b2994d2a29c..cccefd8dfe7 100644 --- a/src/doc/book/src/ffi.md +++ b/src/doc/book/src/ffi.md @@ -680,7 +680,7 @@ pub extern fn hello_rust() -> *const u8 { The `extern` makes this function adhere to the C calling convention, as discussed above in "[Foreign Calling -Conventions](ffi.html#Foreign%20calling%20conventions)". The `no_mangle` +Conventions](ffi.html#foreign-calling-conventions)". The `no_mangle` attribute turns off Rust's name mangling, so that it is easier to link to. # FFI and panics diff --git a/src/doc/book/src/getting-started.md b/src/doc/book/src/getting-started.md index 93846644c39..6208b1f4c12 100644 --- a/src/doc/book/src/getting-started.md +++ b/src/doc/book/src/getting-started.md @@ -236,7 +236,7 @@ language]*, which means that most things are expressions, rather than statements. The `;` indicates that this expression is over, and the next one is ready to begin. Most lines of Rust code end with a `;`. -[expression-oriented language]: glossary.html#Expression-Oriented%20Language +[expression-oriented language]: glossary.html#expression-oriented-language ## Compiling and Running Are Separate Steps diff --git a/src/doc/book/src/glossary.md b/src/doc/book/src/glossary.md index 49821d86a92..b17b89633f3 100644 --- a/src/doc/book/src/glossary.md +++ b/src/doc/book/src/glossary.md @@ -56,7 +56,7 @@ They can be used to manage control flow in a modular fashion. A type without a statically known size or alignment. ([more info][link]) -[link]: ../nomicon/exotic-sizes.html#Dynamically%20Sized%20Types%20(DSTs) +[link]: ../nomicon/exotic-sizes.html#dynamically-sized-types-dsts ### Expression @@ -76,8 +76,8 @@ In an expression-oriented language, (nearly) every statement is an expression and therefore returns a value. Consequently, these expression statements can themselves form part of larger expressions. -[expression]: glossary.html#Expression -[statement]: glossary.html#Statement +[expression]: glossary.html#expression +[statement]: glossary.html#statement ### Statement diff --git a/src/doc/book/src/guessing-game.md b/src/doc/book/src/guessing-game.md index 216db25cd95..7368d2184e5 100644 --- a/src/doc/book/src/guessing-game.md +++ b/src/doc/book/src/guessing-game.md @@ -119,7 +119,7 @@ there are no arguments, and `{` starts the body of the function. Because we didn’t include a return type, it’s assumed to be `()`, an empty [tuple][tuples]. -[tuples]: primitive-types.html#Tuples +[tuples]: primitive-types.html#tuples ```rust,ignore println!("Guess the number!"); @@ -727,7 +727,7 @@ thirty-two bit integer. Rust has [a number of built-in number types][number], but we’ve chosen `u32`. It’s a good default choice for a small positive number. [parse]: ../std/primitive.str.html#method.parse -[number]: primitive-types.html#Numeric%20types +[number]: primitive-types.html#numeric-types Just like `read_line()`, our call to `parse()` could cause an error. What if our string contained `A👍%`? There’d be no way to convert that to a number. As diff --git a/src/doc/book/src/lifetimes.md b/src/doc/book/src/lifetimes.md index c00815f49c7..8bca13c28f0 100644 --- a/src/doc/book/src/lifetimes.md +++ b/src/doc/book/src/lifetimes.md @@ -139,7 +139,7 @@ associated with it, but the compiler lets you elide (i.e. omit, see ["Lifetime Elision"][lifetime-elision] below) them in common cases. Before we get to that, though, let’s look at a short example with explicit lifetimes: -[lifetime-elision]: #Lifetime%20Elision +[lifetime-elision]: #lifetime-elision ```rust,ignore fn bar<'a>(...) diff --git a/src/doc/book/src/macros.md b/src/doc/book/src/macros.md index ae1e1c65dd2..861cb4371f9 100644 --- a/src/doc/book/src/macros.md +++ b/src/doc/book/src/macros.md @@ -430,7 +430,7 @@ Even when Rust code contains un-expanded macros, it can be parsed as a full tools that process code. It also has a few consequences for the design of Rust’s macro system. -[ast]: glossary.html#Abstract%20Syntax%20Tree +[ast]: glossary.html#abstract-syntax-tree One consequence is that Rust must determine, when it parses a macro invocation, whether the macro stands in for diff --git a/src/doc/book/src/mutability.md b/src/doc/book/src/mutability.md index 7e96849220a..fa7a259392a 100644 --- a/src/doc/book/src/mutability.md +++ b/src/doc/book/src/mutability.md @@ -89,7 +89,7 @@ philosophy, memory safety, and the mechanism by which Rust guarantees it, the > * exactly one mutable reference (`&mut T`). [ownership]: ownership.html -[borrowing]: references-and-borrowing.html#Borrowing +[borrowing]: references-and-borrowing.html#borrowing So, that’s the real definition of ‘immutability’: is this safe to have two pointers to? In `Arc`’s case, yes: the mutation is entirely contained inside diff --git a/src/doc/book/src/ownership.md b/src/doc/book/src/ownership.md index e7bf3cec55e..21ebd6333f7 100644 --- a/src/doc/book/src/ownership.md +++ b/src/doc/book/src/ownership.md @@ -65,10 +65,10 @@ elements onto them. Vectors have a [generic type][generics] `Vec`, so in this example `v` will have type `Vec`. We'll cover [generics] in detail in a later chapter. -[arrays]: primitive-types.html#Arrays +[arrays]: primitive-types.html#arrays [vectors]: vectors.html -[heap]: the-stack-and-the-heap.html#The%20Heap -[stack]: the-stack-and-the-heap.html#The%20Stack +[heap]: the-stack-and-the-heap.html#the-heap +[stack]: the-stack-and-the-heap.html#the-stack [bindings]: variable-bindings.html [generics]: generics.html @@ -136,7 +136,7 @@ Rust allocates memory for an integer [i32] on the [stack][sh], copies the bit pattern representing the value of 10 to the allocated memory and binds the variable name x to this memory region for future reference. -[i32]: primitive-types.html#Numeric%20types +[i32]: primitive-types.html#numeric-types Now consider the following code fragment: diff --git a/src/doc/book/src/primitive-types.md b/src/doc/book/src/primitive-types.md index 67d71ceba0c..8fd3d17c15e 100644 --- a/src/doc/book/src/primitive-types.md +++ b/src/doc/book/src/primitive-types.md @@ -232,7 +232,7 @@ soon. You can assign one tuple into another, if they have the same contained types and [arity]. Tuples have the same arity when they have the same length. -[arity]: glossary.html#Arity +[arity]: glossary.html#arity ```rust let mut x = (1, 2); // x: (i32, i32) diff --git a/src/doc/book/src/syntax-index.md b/src/doc/book/src/syntax-index.md index df7ae410ed1..b2cd59c87af 100644 --- a/src/doc/book/src/syntax-index.md +++ b/src/doc/book/src/syntax-index.md @@ -196,18 +196,18 @@ [Associated Types]: associated-types.html [Attributes]: attributes.html [Casting Between Types (`as`)]: casting-between-types.html#as -[Closures (`move` closures)]: closures.html#move%20closures +[Closures (`move` closures)]: closures.html#move-closures [Closures]: closures.html [Comments]: comments.html -[Crates and Modules (Defining Modules)]: crates-and-modules.html#Defining%20modules -[Crates and Modules (Exporting a Public Interface)]: crates-and-modules.html#Exporting%20a%20public%20interface -[Crates and Modules (Importing External Crates)]: crates-and-modules.html#Importing%20external%20crates -[Crates and Modules (Importing Modules with `use`)]: crates-and-modules.html#Importing%20modules%20with%20use -[Crates and Modules (Re-exporting with `pub use`)]: crates-and-modules.html#Re-exporting%20with%20pub%20use -[Diverging Functions]: functions.html#Diverging%20functions +[Crates and Modules (Defining Modules)]: crates-and-modules.html#defining-modules +[Crates and Modules (Exporting a Public Interface)]: crates-and-modules.html#exporting-a-public-interface +[Crates and Modules (Importing External Crates)]: crates-and-modules.html#importing-external-crates +[Crates and Modules (Importing Modules with `use`)]: crates-and-modules.html#importing-modules-with-use +[Crates and Modules (Re-exporting with `pub use`)]: crates-and-modules.html#re-exporting-with-pub-use +[Diverging Functions]: functions.html#diverging-functions [Enums]: enums.html [Foreign Function Interface]: ffi.html -[Functions (Early Returns)]: functions.html#Early%20returns +[Functions (Early Returns)]: functions.html#early-returns [Functions]: functions.html [Generics]: generics.html [Iterators]: iterators.html @@ -216,24 +216,24 @@ [Loops (`for`)]: loops.html#for [Loops (`loop`)]: loops.html#loop [Loops (`while`)]: loops.html#while -[Loops (Ending Iteration Early)]: loops.html#Ending%20iteration%20early -[Loops (Loops Labels)]: loops.html#Loop%20labels +[Loops (Ending Iteration Early)]: loops.html#ending-iteration-early +[Loops (Loops Labels)]: loops.html#loop-labels [Macros]: macros.html [Match]: match.html -[Method Syntax (Method Calls)]: method-syntax.html#Method%20calls +[Method Syntax (Method Calls)]: method-syntax.html#method-calls [Method Syntax]: method-syntax.html [Mutability]: mutability.html [Operators and Overloading]: operators-and-overloading.html -[Patterns (`ref` and `ref mut`)]: patterns.html#ref%20and%20ref%20mut -[Patterns (Bindings)]: patterns.html#Bindings -[Patterns (Ignoring bindings)]: patterns.html#Ignoring%20bindings -[Patterns (Multiple patterns)]: patterns.html#Multiple%20patterns -[Patterns (Ranges)]: patterns.html#Ranges +[Patterns (`ref` and `ref mut`)]: patterns.html#ref-and-ref-mut +[Patterns (Bindings)]: patterns.html#bindings +[Patterns (Ignoring bindings)]: patterns.html#ignoring-bindings +[Patterns (Multiple patterns)]: patterns.html#multiple-patterns +[Patterns (Ranges)]: patterns.html#ranges [Primitive Types (`char`)]: primitive-types.html#char -[Primitive Types (Arrays)]: primitive-types.html#Arrays -[Primitive Types (Booleans)]: primitive-types.html#Booleans -[Primitive Types (Tuple Indexing)]: primitive-types.html#Tuple%20indexing -[Primitive Types (Tuples)]: primitive-types.html#Tuples +[Primitive Types (Arrays)]: primitive-types.html#arrays +[Primitive Types (Booleans)]: primitive-types.html#booleans +[Primitive Types (Tuple Indexing)]: primitive-types.html#tuple-indexing +[Primitive Types (Tuples)]: primitive-types.html#tuples [Raw Pointers]: raw-pointers.html [Reference (Byte String Literals)]: ../reference.html#byte-string-literals [Reference (Integer literals)]: ../reference.html#integer-literals @@ -241,13 +241,13 @@ [Reference (Raw String Literals)]: ../reference.html#raw-string-literals [References and Borrowing]: references-and-borrowing.html [Strings]: strings.html -[Structs (Update syntax)]: structs.html#Update%20syntax +[Structs (Update syntax)]: structs.html#update-syntax [Structs]: structs.html -[Traits (`where` clause)]: traits.html#Where%20clause -[Traits (Multiple Trait Bounds)]: traits.html#Multiple%20trait%20bounds +[Traits (`where` clause)]: traits.html#where-clause +[Traits (Multiple Trait Bounds)]: traits.html#multiple-trait-bounds [Traits]: traits.html [Universal Function Call Syntax]: ufcs.html -[Universal Function Call Syntax (Angle-bracket Form)]: ufcs.html#Angle-bracket%20Form +[Universal Function Call Syntax (Angle-bracket Form)]: ufcs.html#angle-bracket-form [Unsafe]: unsafe.html -[Unsized Types (`?Sized`)]: unsized-types.html#Sized +[Unsized Types (`?Sized`)]: unsized-types.html#sized [Variable Bindings]: variable-bindings.html diff --git a/src/doc/book/src/traits.md b/src/doc/book/src/traits.md index a6d1c3d1d23..19a133f84b0 100644 --- a/src/doc/book/src/traits.md +++ b/src/doc/book/src/traits.md @@ -81,7 +81,7 @@ Traits are useful because they allow a type to make certain promises about its behavior. Generic functions can exploit this to constrain, or [bound][bounds], the types they accept. Consider this function, which does not compile: -[bounds]: glossary.html#Bounds +[bounds]: glossary.html#bounds ```rust,ignore fn print_area(shape: T) { diff --git a/src/doc/book/src/type-aliases.md b/src/doc/book/src/type-aliases.md index b1ce0685283..1bd0f78e368 100644 --- a/src/doc/book/src/type-aliases.md +++ b/src/doc/book/src/type-aliases.md @@ -55,7 +55,7 @@ if x == y { This compiles without error. Values of a `Num` type are the same as a value of type `i32`, in every way. You can use [tuple struct] to really get a new type. -[tuple struct]: structs.html#Tuple%20structs +[tuple struct]: structs.html#tuple-structs You can also use type aliases with generics: diff --git a/src/doc/book/src/vectors.md b/src/doc/book/src/vectors.md index 9b293880cdc..aff078718df 100644 --- a/src/doc/book/src/vectors.md +++ b/src/doc/book/src/vectors.md @@ -151,6 +151,6 @@ API documentation][vec]. [vec]: ../std/vec/index.html [box]: ../std/boxed/index.html [generic]: generics.html -[panic]: concurrency.html#Panics +[panic]: concurrency.html#panics [get]: ../std/vec/struct.Vec.html#method.get [get_mut]: ../std/vec/struct.Vec.html#method.get_mut diff --git a/src/doc/nomicon/src/lifetime-mismatch.md b/src/doc/nomicon/src/lifetime-mismatch.md index 08627130590..30b4f09f903 100644 --- a/src/doc/nomicon/src/lifetime-mismatch.md +++ b/src/doc/nomicon/src/lifetime-mismatch.md @@ -78,4 +78,4 @@ TODO: other common problems? SEME regions stuff, mostly? -[ex2]: lifetimes.html#Example%3A%20aliasing%20a%20mutable%20reference +[ex2]: lifetimes.html#example-aliasing-a-mutable-reference diff --git a/src/doc/nomicon/src/repr-rust.md b/src/doc/nomicon/src/repr-rust.md index 98411e041be..c02cf44189f 100644 --- a/src/doc/nomicon/src/repr-rust.md +++ b/src/doc/nomicon/src/repr-rust.md @@ -151,4 +151,4 @@ use fairly elaborate algorithms to cache bits throughout nested types with special constrained representations. As such it is *especially* desirable that we leave enum layout unspecified today. -[dst]: exotic-sizes.html#Dynamically%20Sized%20Types%20(DSTs) +[dst]: exotic-sizes.html#dynamically-sized-types-dsts diff --git a/src/doc/reference.md b/src/doc/reference.md index f2be20d4a75..15645fa9e31 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -2108,7 +2108,7 @@ On `struct`s: list of names `#[macro_use(foo, bar)]` restricts the import to just those macros named. The `extern crate` must appear at the crate root, not inside `mod`, which ensures proper function of the [`$crate` macro - variable](book/macros.html#The%20variable%20%24crate). + variable](book/macros.html#the-variable-crate). - `macro_reexport` on an `extern crate` — re-export the named macros. @@ -2118,7 +2118,7 @@ On `struct`s: link it into the output. See the [macros section of the -book](book/macros.html#Scoping%20and%20macro%20import%2Fexport) for more information on +book](book/macros.html#scoping-and-macro-importexport) for more information on macro scope. @@ -2277,7 +2277,7 @@ For any lint check `C`: The lint checks supported by the compiler can be found via `rustc -W help`, along with their default settings. [Compiler -plugins](book/compiler-plugins.html#Lint%20plugins) can provide additional lint checks. +plugins](book/compiler-plugins.html#lint-plugins) can provide additional lint checks. ```{.ignore} pub mod m1 { diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 210917b68a2..38d843263ff 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -102,7 +102,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// [downgrade]: struct.Arc.html#method.downgrade /// [upgrade]: struct.Weak.html#method.upgrade /// [`None`]: ../../std/option/enum.Option.html#variant.None -/// [assoc]: ../../book/method-syntax.html#Associated%20functions +/// [assoc]: ../../book/method-syntax.html#associated-functions /// /// # Examples /// diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index a874e938a40..6108a06634b 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -215,7 +215,7 @@ //! [downgrade]: struct.Rc.html#method.downgrade //! [upgrade]: struct.Weak.html#method.upgrade //! [`None`]: ../../std/option/enum.Option.html#variant.None -//! [assoc]: ../../book/method-syntax.html#Associated%20functions +//! [assoc]: ../../book/method-syntax.html#associated-functions //! [mutability]: ../../std/cell/index.html#introducing-mutability-inside-of-something-immutable #![stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 5655fd06604..209107ef92c 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -525,7 +525,7 @@ pub fn replace(dest: &mut T, mut src: T) -> T { /// it will not release any borrows, as borrows are based on lexical scope. /// /// This effectively does nothing for -/// [types which implement `Copy`](../../book/ownership.html#Copy%20types), +/// [types which implement `Copy`](../../book/ownership.html#copy-types), /// e.g. integers. Such values are copied and _then_ moved into the function, /// so the value persists after this function call. /// diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs index 652b139f1e6..a7d0d3899b1 100644 --- a/src/libcore/raw.rs +++ b/src/libcore/raw.rs @@ -25,7 +25,7 @@ /// Book][moreinfo] contains more details about the precise nature of /// these internals. /// -/// [moreinfo]: ../../book/trait-objects.html#Representation +/// [moreinfo]: ../../book/trait-objects.html#representation /// /// `TraitObject` is guaranteed to match layouts, but it is not the /// type of trait objects (e.g. the fields are not directly accessible diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 939f214407e..9295fb2ee32 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -65,9 +65,6 @@ use super::region_inference::ConcreteFailure; use super::region_inference::SubSupConflict; use super::region_inference::GenericBoundFailure; use super::region_inference::GenericKind; -use super::region_inference::ProcessedErrors; -use super::region_inference::ProcessedErrorOrigin; -use super::region_inference::SameRegions; use hir::map as hir_map; use hir; @@ -77,11 +74,10 @@ use infer; use middle::region; use traits::{ObligationCause, ObligationCauseCode}; use ty::{self, TyCtxt, TypeFoldable}; -use ty::{Region, ReFree, Issue32330}; +use ty::{Region, Issue32330}; use ty::error::TypeError; use std::fmt; -use syntax::ast; use syntax_pos::{Pos, Span}; use errors::DiagnosticBuilder; @@ -255,8 +251,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // try to pre-process the errors, which will group some of them // together into a `ProcessedErrors` group: - let processed_errors = self.process_errors(errors); - let errors = processed_errors.as_ref().unwrap_or(errors); + let errors = self.process_errors(errors); debug!("report_region_errors: {} errors after preprocessing", errors.len()); @@ -278,13 +273,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { sub_origin, sub_r, sup_origin, sup_r); } - - ProcessedErrors(ref origins, - ref same_regions) => { - if !same_regions.is_empty() { - self.report_processed_errors(origins); - } - } } } } @@ -300,202 +288,31 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // duplicates that will be unhelpful to the end-user. But // obviously it never weeds out ALL errors. fn process_errors(&self, errors: &Vec>) - -> Option>> { + -> Vec> { debug!("process_errors()"); - let mut origins = Vec::new(); - // we collect up ConcreteFailures and SubSupConflicts that are - // relating free-regions bound on the fn-header and group them - // together into this vector - let mut same_regions = Vec::new(); + // We want to avoid reporting generic-bound failures if we can + // avoid it: these have a very high rate of being unhelpful in + // practice. This is because they are basically secondary + // checks that test the state of the region graph after the + // rest of inference is done, and the other kinds of errors + // indicate that the region constraint graph is internally + // inconsistent, so these test results are likely to be + // meaningless. + // + // Therefore, we filter them out of the list unless they are + // the only thing in the list. - // here we put errors that we will not be able to process nicely - let mut other_errors = Vec::new(); + let is_bound_failure = |e: &RegionResolutionError<'tcx>| match *e { + ConcreteFailure(..) => false, + SubSupConflict(..) => false, + GenericBoundFailure(..) => true, + }; - // we collect up GenericBoundFailures in here. - let mut bound_failures = Vec::new(); - - for error in errors { - // Check whether we can process this error into some other - // form; if not, fall through. - match *error { - ConcreteFailure(ref origin, sub, sup) => { - debug!("processing ConcreteFailure"); - if let SubregionOrigin::CompareImplMethodObligation { .. } = *origin { - // When comparing an impl method against a - // trait method, it is not helpful to suggest - // changes to the impl method. This is - // because the impl method signature is being - // checked using the trait's environment, so - // usually the changes we suggest would - // actually have to be applied to the *trait* - // method (and it's not clear that the trait - // method is even under the user's control). - } else if let Some(same_frs) = free_regions_from_same_fn(self.tcx, sub, sup) { - origins.push( - ProcessedErrorOrigin::ConcreteFailure( - origin.clone(), - sub, - sup)); - append_to_same_regions(&mut same_regions, &same_frs); - continue; - } - } - SubSupConflict(ref var_origin, ref sub_origin, sub, ref sup_origin, sup) => { - debug!("processing SubSupConflict sub: {:?} sup: {:?}", sub, sup); - match (sub_origin, sup_origin) { - (&SubregionOrigin::CompareImplMethodObligation { .. }, _) => { - // As above, when comparing an impl method - // against a trait method, it is not helpful - // to suggest changes to the impl method. - } - (_, &SubregionOrigin::CompareImplMethodObligation { .. }) => { - // See above. - } - _ => { - if let Some(same_frs) = free_regions_from_same_fn(self.tcx, sub, sup) { - origins.push( - ProcessedErrorOrigin::VariableFailure( - var_origin.clone())); - append_to_same_regions(&mut same_regions, &same_frs); - continue; - } - } - } - } - GenericBoundFailure(ref origin, ref kind, region) => { - bound_failures.push((origin.clone(), kind.clone(), region)); - continue; - } - ProcessedErrors(..) => { - bug!("should not encounter a `ProcessedErrors` yet: {:?}", error) - } - } - - // No changes to this error. - other_errors.push(error.clone()); - } - - // ok, let's pull together the errors, sorted in an order that - // we think will help user the best - let mut processed_errors = vec![]; - - // first, put the processed errors, if any - if !same_regions.is_empty() { - let common_scope_id = same_regions[0].scope_id; - for sr in &same_regions { - // Since ProcessedErrors is used to reconstruct the function - // declaration, we want to make sure that they are, in fact, - // from the same scope - if sr.scope_id != common_scope_id { - debug!("returning empty result from process_errors because - {} != {}", sr.scope_id, common_scope_id); - return None; - } - } - assert!(origins.len() > 0); - let pe = ProcessedErrors(origins, same_regions); - debug!("errors processed: {:?}", pe); - processed_errors.push(pe); - } - - // next, put the other misc errors - processed_errors.extend(other_errors); - - // finally, put the `T: 'a` errors, but only if there were no - // other errors. otherwise, these have a very high rate of - // being unhelpful in practice. This is because they are - // basically secondary checks that test the state of the - // region graph after the rest of inference is done, and the - // other kinds of errors indicate that the region constraint - // graph is internally inconsistent, so these test results are - // likely to be meaningless. - if processed_errors.is_empty() { - for (origin, kind, region) in bound_failures { - processed_errors.push(GenericBoundFailure(origin, kind, region)); - } - } - - // we should always wind up with SOME errors, unless there were no - // errors to start - assert!(if errors.len() > 0 {processed_errors.len() > 0} else {true}); - - return Some(processed_errors); - - #[derive(Debug)] - struct FreeRegionsFromSameFn { - sub_fr: ty::FreeRegion, - sup_fr: ty::FreeRegion, - scope_id: ast::NodeId - } - - impl FreeRegionsFromSameFn { - fn new(sub_fr: ty::FreeRegion, - sup_fr: ty::FreeRegion, - scope_id: ast::NodeId) - -> FreeRegionsFromSameFn { - FreeRegionsFromSameFn { - sub_fr: sub_fr, - sup_fr: sup_fr, - scope_id: scope_id - } - } - } - - fn free_regions_from_same_fn<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - sub: &'tcx Region, - sup: &'tcx Region) - -> Option { - debug!("free_regions_from_same_fn(sub={:?}, sup={:?})", sub, sup); - let (scope_id, fr1, fr2) = match (sub, sup) { - (&ReFree(fr1), &ReFree(fr2)) => { - if fr1.scope != fr2.scope { - return None - } - assert!(fr1.scope == fr2.scope); - (fr1.scope.node_id(&tcx.region_maps), fr1, fr2) - }, - _ => return None - }; - let parent = tcx.hir.get_parent(scope_id); - let parent_node = tcx.hir.find(parent); - match parent_node { - Some(node) => match node { - hir_map::NodeItem(item) => match item.node { - hir::ItemFn(..) => { - Some(FreeRegionsFromSameFn::new(fr1, fr2, scope_id)) - }, - _ => None - }, - hir_map::NodeImplItem(..) | - hir_map::NodeTraitItem(..) => { - Some(FreeRegionsFromSameFn::new(fr1, fr2, scope_id)) - }, - _ => None - }, - None => { - debug!("no parent node of scope_id {}", scope_id); - None - } - } - } - - fn append_to_same_regions(same_regions: &mut Vec, - same_frs: &FreeRegionsFromSameFn) { - debug!("append_to_same_regions(same_regions={:?}, same_frs={:?})", - same_regions, same_frs); - let scope_id = same_frs.scope_id; - let (sub_fr, sup_fr) = (same_frs.sub_fr, same_frs.sup_fr); - for sr in same_regions.iter_mut() { - if sr.contains(&sup_fr.bound_region) && scope_id == sr.scope_id { - sr.push(sub_fr.bound_region); - return - } - } - same_regions.push(SameRegions { - scope_id: scope_id, - regions: vec![sub_fr.bound_region, sup_fr.bound_region] - }) + if errors.iter().all(|e| is_bound_failure(e)) { + errors.clone() + } else { + errors.iter().filter(|&e| !is_bound_failure(e)).cloned().collect() } } @@ -1072,20 +889,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.note_region_origin(&mut err, &sub_origin); err.emit(); } - - fn report_processed_errors(&self, - origins: &[ProcessedErrorOrigin<'tcx>]) { - for origin in origins.iter() { - let mut err = match *origin { - ProcessedErrorOrigin::VariableFailure(ref var_origin) => - self.report_inference_failure(var_origin.clone()), - ProcessedErrorOrigin::ConcreteFailure(ref sr_origin, sub, sup) => - self.report_concrete_failure(sr_origin.clone(), sub, sup), - }; - - err.emit(); - } - } } impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { diff --git a/src/librustc/infer/region_inference/mod.rs b/src/librustc/infer/region_inference/mod.rs index af6f2c50e72..0bb9e2c7fa1 100644 --- a/src/librustc/infer/region_inference/mod.rs +++ b/src/librustc/infer/region_inference/mod.rs @@ -24,7 +24,7 @@ use rustc_data_structures::graph::{self, Direction, NodeIndex, OUTGOING}; use rustc_data_structures::unify::{self, UnificationTable}; use middle::free_region::FreeRegionMap; use ty::{self, Ty, TyCtxt}; -use ty::{BoundRegion, Region, RegionVid}; +use ty::{Region, RegionVid}; use ty::{ReEmpty, ReStatic, ReFree, ReEarlyBound, ReErased}; use ty::{ReLateBound, ReScope, ReVar, ReSkolemized, BrFresh}; @@ -171,13 +171,6 @@ pub enum RegionResolutionError<'tcx> { &'tcx Region, SubregionOrigin<'tcx>, &'tcx Region), - - /// For subsets of `ConcreteFailure` and `SubSupConflict`, we can derive - /// more specific errors message by suggesting to the user where they - /// should put a lifetime. In those cases we process and put those errors - /// into `ProcessedErrors` before we do any reporting. - ProcessedErrors(Vec>, - Vec), } #[derive(Clone, Debug)] @@ -186,33 +179,6 @@ pub enum ProcessedErrorOrigin<'tcx> { VariableFailure(RegionVariableOrigin), } -/// SameRegions is used to group regions that we think are the same and would -/// like to indicate so to the user. -/// For example, the following function -/// ``` -/// struct Foo { bar: i32 } -/// fn foo2<'a, 'b>(x: &'a Foo) -> &'b i32 { -/// &x.bar -/// } -/// ``` -/// would report an error because we expect 'a and 'b to match, and so we group -/// 'a and 'b together inside a SameRegions struct -#[derive(Clone, Debug)] -pub struct SameRegions { - pub scope_id: ast::NodeId, - pub regions: Vec, -} - -impl SameRegions { - pub fn contains(&self, other: &BoundRegion) -> bool { - self.regions.contains(other) - } - - pub fn push(&mut self, other: BoundRegion) { - self.regions.push(other); - } -} - pub type CombineMap<'tcx> = FxHashMap, RegionVid>; pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 079dbd667d6..fd5827b4c07 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -182,15 +182,15 @@ impl DefaultResizePolicy { // ---------------------- // To protect against degenerate performance scenarios (including DOS attacks), // the implementation includes an adaptive behavior that can resize the map -// early (before it's capacity is exceeded) when suspiciously long probe or -// foward shifts sequences are encounted. +// early (before its capacity is exceeded) when suspiciously long probe or +// forward shifts sequences are encountered. // // With this algorithm in place it would be possible to turn a CPU attack into -// a memory attack due to the agressive resizing. To prevent that the +// a memory attack due to the aggressive resizing. To prevent that the // adaptive behavior only triggers when the map occupancy is half the maximum occupancy. -// This reduces the effectivenes of the algorithm but also makes it completelly safe. +// This reduces the effectiveness of the algorithm but also makes it completely safe. // -// The previous safety measure that also prevents degenerate iteractions with +// The previous safety measure also prevents degenerate interactions with // really bad quality hash algorithms that can make normal inputs look like a // DOS attack. // diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 88c2310a86e..070690773b6 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -189,8 +189,8 @@ //! [`sync`]: sync/index.html //! [`thread`]: thread/index.html //! [`use std::env`]: env/index.html -//! [`use`]: ../book/crates-and-modules.html#Importing%20Modules%20with%20use -//! [crate root]: ../book/crates-and-modules.html#Basic%20terminology%3A%20Crates%20and%20Modules +//! [`use`]: ../book/crates-and-modules.html#importing-modules-with-use +//! [crate root]: ../book/crates-and-modules.html#basic-terminology-crates-and-modules //! [crates.io]: https://crates.io //! [deref coercions]: ../book/deref-coercions.html //! [files]: fs/struct.File.html diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 1b3e17c300e..11197db98a3 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -490,7 +490,7 @@ mod prim_str { } /// assert_eq!(tuple.2, 'c'); /// ``` /// -/// For more about tuples, see [the book](../book/primitive-types.html#Tuples). +/// For more about tuples, see [the book](../book/primitive-types.html#tuples). /// /// # Trait implementations /// diff --git a/src/test/compile-fail/issue-17728.rs b/src/test/compile-fail/issue-17728.rs index f508d7123d8..9724d17bef1 100644 --- a/src/test/compile-fail/issue-17728.rs +++ b/src/test/compile-fail/issue-17728.rs @@ -108,9 +108,6 @@ impl Debug for Player { fn str_to_direction(to_parse: &str) -> RoomDirection { match to_parse { //~ ERROR match arms have incompatible types - //~^ expected enum `RoomDirection`, found enum `std::option::Option` - //~| expected type `RoomDirection` - //~| found type `std::option::Option<_>` "w" | "west" => RoomDirection::West, "e" | "east" => RoomDirection::East, "n" | "north" => RoomDirection::North, @@ -119,7 +116,7 @@ fn str_to_direction(to_parse: &str) -> RoomDirection { "out" => RoomDirection::Out, "up" => RoomDirection::Up, "down" => RoomDirection::Down, - _ => None //~ NOTE match arm with an incompatible type + _ => None } } diff --git a/src/test/run-pass/const-enum-vec-index.rs b/src/test/run-pass/const-enum-vec-index.rs index 4af6a6d10d5..9c1a4dbdffa 100644 --- a/src/test/run-pass/const-enum-vec-index.rs +++ b/src/test/run-pass/const-enum-vec-index.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[derive(Copy, Clone)] enum E { V1(isize), V0 } + const C: &'static [E] = &[E::V0, E::V1(0xDEADBEE)]; static C0: E = C[0]; static C1: E = C[1]; diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.rs b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.rs new file mode 100644 index 00000000000..30239f4c094 --- /dev/null +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.rs @@ -0,0 +1,15 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { + if x > y { x } else { y } +} + +fn main() { } diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr new file mode 100644 index 00000000000..85e05422ab3 --- /dev/null +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr @@ -0,0 +1,25 @@ +error[E0312]: lifetime of reference outlives lifetime of borrowed content... + --> $DIR/ex1-return-one-existing-name-if-else.rs:12:27 + | +12 | if x > y { x } else { y } + | ^ + | +note: ...the reference is valid for the lifetime 'a as defined on the body at 11:43... + --> $DIR/ex1-return-one-existing-name-if-else.rs:11:44 + | +11 | fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { + | ____________________________________________^ starting here... +12 | | if x > y { x } else { y } +13 | | } + | |_^ ...ending here +note: ...but the borrowed content is only valid for the anonymous lifetime #1 defined on the body at 11:43 + --> $DIR/ex1-return-one-existing-name-if-else.rs:11:44 + | +11 | fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { + | ____________________________________________^ starting here... +12 | | if x > y { x } else { y } +13 | | } + | |_^ ...ending here + +error: aborting due to previous error + diff --git a/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.rs b/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.rs new file mode 100644 index 00000000000..098950e13b3 --- /dev/null +++ b/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.rs @@ -0,0 +1,15 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn foo(x: &i32, y: &i32) -> &i32 { + if x > y { x } else { y } +} + +fn main() { } diff --git a/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr b/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr new file mode 100644 index 00000000000..fccc44caac8 --- /dev/null +++ b/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr @@ -0,0 +1,10 @@ +error[E0106]: missing lifetime specifier + --> $DIR/ex1b-return-no-names-if-else.rs:11:29 + | +11 | fn foo(x: &i32, y: &i32) -> &i32 { + | ^ expected lifetime parameter + | + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` + +error: aborting due to previous error + diff --git a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.rs b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.rs new file mode 100644 index 00000000000..71a1c865e09 --- /dev/null +++ b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.rs @@ -0,0 +1,19 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Ref<'a, T: 'a> { + data: &'a T +} + +fn foo<'a>(x: &mut Vec>, y: Ref) { + x.push(y); +} + +fn main() { } diff --git a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr new file mode 100644 index 00000000000..6f42a9f679a --- /dev/null +++ b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr @@ -0,0 +1,27 @@ +error[E0308]: mismatched types + --> $DIR/ex2a-push-one-existing-name.rs:16:12 + | +16 | x.push(y); + | ^ lifetime mismatch + | + = note: expected type `Ref<'a, i32>` + found type `Ref<'_, i32>` +note: the anonymous lifetime #2 defined on the body at 15:51... + --> $DIR/ex2a-push-one-existing-name.rs:15:52 + | +15 | fn foo<'a>(x: &mut Vec>, y: Ref) { + | ____________________________________________________^ starting here... +16 | | x.push(y); +17 | | } + | |_^ ...ending here +note: ...does not necessarily outlive the lifetime 'a as defined on the body at 15:51 + --> $DIR/ex2a-push-one-existing-name.rs:15:52 + | +15 | fn foo<'a>(x: &mut Vec>, y: Ref) { + | ____________________________________________________^ starting here... +16 | | x.push(y); +17 | | } + | |_^ ...ending here + +error: aborting due to previous error + diff --git a/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.rs b/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.rs new file mode 100644 index 00000000000..09038d8ce90 --- /dev/null +++ b/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.rs @@ -0,0 +1,19 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Ref<'a, T: 'a> { + data: &'a T +} + +fn foo(x: &mut Vec>, y: Ref) { + x.push(y); +} + +fn main() { } diff --git a/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr b/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr new file mode 100644 index 00000000000..edc1c2362de --- /dev/null +++ b/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr @@ -0,0 +1,27 @@ +error[E0308]: mismatched types + --> $DIR/ex2b-push-no-existing-names.rs:16:12 + | +16 | x.push(y); + | ^ lifetime mismatch + | + = note: expected type `Ref<'_, i32>` + found type `Ref<'_, i32>` +note: the anonymous lifetime #3 defined on the body at 15:43... + --> $DIR/ex2b-push-no-existing-names.rs:15:44 + | +15 | fn foo(x: &mut Vec>, y: Ref) { + | ____________________________________________^ starting here... +16 | | x.push(y); +17 | | } + | |_^ ...ending here +note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 15:43 + --> $DIR/ex2b-push-no-existing-names.rs:15:44 + | +15 | fn foo(x: &mut Vec>, y: Ref) { + | ____________________________________________^ starting here... +16 | | x.push(y); +17 | | } + | |_^ ...ending here + +error: aborting due to previous error + diff --git a/src/test/ui/lifetime-errors/ex2c-push-inference-variable.rs b/src/test/ui/lifetime-errors/ex2c-push-inference-variable.rs new file mode 100644 index 00000000000..cb083f778de --- /dev/null +++ b/src/test/ui/lifetime-errors/ex2c-push-inference-variable.rs @@ -0,0 +1,20 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Ref<'a, T: 'a> { + data: &'a T +} + +fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { + let z = Ref { data: y.data }; + x.push(z); +} + +fn main() { } diff --git a/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr b/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr new file mode 100644 index 00000000000..755b71d4a1d --- /dev/null +++ b/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr @@ -0,0 +1,37 @@ +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements + --> $DIR/ex2c-push-inference-variable.rs:16:13 + | +16 | let z = Ref { data: y.data }; + | ^^^ + | +note: first, the lifetime cannot outlive the lifetime 'c as defined on the body at 15:66... + --> $DIR/ex2c-push-inference-variable.rs:15:67 + | +15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { + | ___________________________________________________________________^ starting here... +16 | | let z = Ref { data: y.data }; +17 | | x.push(z); +18 | | } + | |_^ ...ending here +note: ...so that reference does not outlive borrowed content + --> $DIR/ex2c-push-inference-variable.rs:16:25 + | +16 | let z = Ref { data: y.data }; + | ^^^^^^ +note: but, the lifetime must be valid for the lifetime 'b as defined on the body at 15:66... + --> $DIR/ex2c-push-inference-variable.rs:15:67 + | +15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { + | ___________________________________________________________________^ starting here... +16 | | let z = Ref { data: y.data }; +17 | | x.push(z); +18 | | } + | |_^ ...ending here +note: ...so that expression is assignable (expected Ref<'b, i32>, found Ref<'_, i32>) + --> $DIR/ex2c-push-inference-variable.rs:17:12 + | +17 | x.push(z); + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.rs b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.rs new file mode 100644 index 00000000000..bcb7583beef --- /dev/null +++ b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.rs @@ -0,0 +1,21 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Ref<'a, T: 'a> { + data: &'a T +} + +fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { + let a: &mut Vec> = x; + let b = Ref { data: y.data }; + a.push(b); +} + +fn main() { } diff --git a/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr new file mode 100644 index 00000000000..daa6ea2d91a --- /dev/null +++ b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr @@ -0,0 +1,39 @@ +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements + --> $DIR/ex2d-push-inference-variable-2.rs:17:13 + | +17 | let b = Ref { data: y.data }; + | ^^^ + | +note: first, the lifetime cannot outlive the lifetime 'c as defined on the body at 15:66... + --> $DIR/ex2d-push-inference-variable-2.rs:15:67 + | +15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { + | ___________________________________________________________________^ starting here... +16 | | let a: &mut Vec> = x; +17 | | let b = Ref { data: y.data }; +18 | | a.push(b); +19 | | } + | |_^ ...ending here +note: ...so that reference does not outlive borrowed content + --> $DIR/ex2d-push-inference-variable-2.rs:17:25 + | +17 | let b = Ref { data: y.data }; + | ^^^^^^ +note: but, the lifetime must be valid for the lifetime 'b as defined on the body at 15:66... + --> $DIR/ex2d-push-inference-variable-2.rs:15:67 + | +15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { + | ___________________________________________________________________^ starting here... +16 | | let a: &mut Vec> = x; +17 | | let b = Ref { data: y.data }; +18 | | a.push(b); +19 | | } + | |_^ ...ending here +note: ...so that expression is assignable (expected &mut std::vec::Vec>, found &mut std::vec::Vec>) + --> $DIR/ex2d-push-inference-variable-2.rs:16:33 + | +16 | let a: &mut Vec> = x; + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.rs b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.rs new file mode 100644 index 00000000000..2d05adb7ecd --- /dev/null +++ b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.rs @@ -0,0 +1,21 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Ref<'a, T: 'a> { + data: &'a T +} + +fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { + let a: &mut Vec> = x; + let b = Ref { data: y.data }; + Vec::push(a, b); +} + +fn main() { } diff --git a/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr new file mode 100644 index 00000000000..b679532a4d9 --- /dev/null +++ b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr @@ -0,0 +1,39 @@ +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements + --> $DIR/ex2e-push-inference-variable-3.rs:17:13 + | +17 | let b = Ref { data: y.data }; + | ^^^ + | +note: first, the lifetime cannot outlive the lifetime 'c as defined on the body at 15:66... + --> $DIR/ex2e-push-inference-variable-3.rs:15:67 + | +15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { + | ___________________________________________________________________^ starting here... +16 | | let a: &mut Vec> = x; +17 | | let b = Ref { data: y.data }; +18 | | Vec::push(a, b); +19 | | } + | |_^ ...ending here +note: ...so that reference does not outlive borrowed content + --> $DIR/ex2e-push-inference-variable-3.rs:17:25 + | +17 | let b = Ref { data: y.data }; + | ^^^^^^ +note: but, the lifetime must be valid for the lifetime 'b as defined on the body at 15:66... + --> $DIR/ex2e-push-inference-variable-3.rs:15:67 + | +15 | fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { + | ___________________________________________________________________^ starting here... +16 | | let a: &mut Vec> = x; +17 | | let b = Ref { data: y.data }; +18 | | Vec::push(a, b); +19 | | } + | |_^ ...ending here +note: ...so that expression is assignable (expected &mut std::vec::Vec>, found &mut std::vec::Vec>) + --> $DIR/ex2e-push-inference-variable-3.rs:16:33 + | +16 | let a: &mut Vec> = x; + | ^ + +error: aborting due to previous error + diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 304c722bbe5..ba5ca44526b 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -65,6 +65,7 @@ enum Redirect { struct FileEntry { source: String, ids: HashSet, + names: HashSet, } type Cache = HashMap; @@ -81,6 +82,15 @@ impl FileEntry { }); } } + + fn parse_names(&mut self, contents: &str) { + if self.names.is_empty() { + with_attrs_in_source(contents, " name", |fragment, _| { + let frag = fragment.trim_left_matches("#").to_owned(); + self.names.insert(frag); + }); + } + } } fn walk(cache: &mut Cache, root: &Path, dir: &Path, errors: &mut bool) { @@ -139,6 +149,9 @@ fn check(cache: &mut Cache, cache.get_mut(&pretty_file) .unwrap() .parse_ids(&pretty_file, &contents, errors); + cache.get_mut(&pretty_file) + .unwrap() + .parse_names(&contents); } // Search for anything that's the regex 'href[ ]*=[ ]*".*?"' @@ -209,13 +222,6 @@ fn check(cache: &mut Cache, Err(LoadError::IsRedirect) => unreachable!(), }; - // we don't check the book for fragments because they're added via JS - for book in ["book/", "nomicon/"].iter() { - if !pretty_path.to_str().unwrap().starts_with(book) { - return; - } - } - if let Some(ref fragment) = fragment { // Fragments like `#1-6` are most likely line numbers to be // interpreted by javascript, so we're ignoring these @@ -226,8 +232,9 @@ fn check(cache: &mut Cache, let entry = &mut cache.get_mut(&pretty_path).unwrap(); entry.parse_ids(&pretty_path, &contents, errors); + entry.parse_names(&contents); - if !entry.ids.contains(*fragment) { + if !(entry.ids.contains(*fragment) || entry.names.contains(*fragment)) { *errors = true; print!("{}:{}: broken link fragment ", pretty_file.display(), @@ -277,6 +284,7 @@ fn load_file(cache: &mut Cache, entry.insert(FileEntry { source: contents.clone(), ids: HashSet::new(), + names: HashSet::new(), }); } maybe diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index 391ffe2e8e9..f7a452d9f7b 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -8,5 +8,5 @@ license = "MIT/Apache-2.0" clap = "2.19.3" [dependencies.mdbook] -version = "0.0.15" +version = "0.0.16" default-features = false