about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-02-20 18:58:28 +0000
committerbors <bors@rust-lang.org>2017-02-20 18:58:28 +0000
commitc1368fc4f497b6387b00850dc5a95df5d6974b43 (patch)
treebe7ffac7211cbedf53d95320197a17ec97248a49
parent5b7c5563855123ab094db99d42ccab5f26dbccdf (diff)
parent9a8dbbe918da20eb75b924ecc0742e42c70c3709 (diff)
downloadrust-c1368fc4f497b6387b00850dc5a95df5d6974b43.tar.gz
rust-c1368fc4f497b6387b00850dc5a95df5d6974b43.zip
Auto merge of #39981 - frewsxcv:rollup, r=frewsxcv
Rollup of 3 pull requests

- Successful merges: #39913, #39937, #39976
- Failed merges:
-rw-r--r--src/Cargo.lock6
-rw-r--r--src/doc/book/src/casting-between-types.md2
-rw-r--r--src/doc/book/src/closures.md2
-rw-r--r--src/doc/book/src/compiler-plugins.md2
-rw-r--r--src/doc/book/src/concurrency.md4
-rw-r--r--src/doc/book/src/error-handling.md72
-rw-r--r--src/doc/book/src/ffi.md2
-rw-r--r--src/doc/book/src/getting-started.md2
-rw-r--r--src/doc/book/src/glossary.md6
-rw-r--r--src/doc/book/src/guessing-game.md4
-rw-r--r--src/doc/book/src/lifetimes.md2
-rw-r--r--src/doc/book/src/macros.md2
-rw-r--r--src/doc/book/src/mutability.md2
-rw-r--r--src/doc/book/src/ownership.md8
-rw-r--r--src/doc/book/src/primitive-types.md2
-rw-r--r--src/doc/book/src/syntax-index.md50
-rw-r--r--src/doc/book/src/traits.md2
-rw-r--r--src/doc/book/src/type-aliases.md2
-rw-r--r--src/doc/book/src/vectors.md2
-rw-r--r--src/doc/nomicon/src/lifetime-mismatch.md2
-rw-r--r--src/doc/nomicon/src/repr-rust.md2
-rw-r--r--src/doc/reference.md6
-rw-r--r--src/liballoc/arc.rs2
-rw-r--r--src/liballoc/rc.rs2
-rw-r--r--src/libcore/mem.rs2
-rw-r--r--src/libcore/raw.rs2
-rw-r--r--src/librustc/infer/error_reporting.rs245
-rw-r--r--src/librustc/infer/region_inference/mod.rs36
-rw-r--r--src/libstd/collections/hash/map.rs10
-rw-r--r--src/libstd/lib.rs4
-rw-r--r--src/libstd/primitive_docs.rs2
-rw-r--r--src/test/compile-fail/issue-17728.rs5
-rw-r--r--src/test/run-pass/const-enum-vec-index.rs2
-rw-r--r--src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.rs15
-rw-r--r--src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr25
-rw-r--r--src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.rs15
-rw-r--r--src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr10
-rw-r--r--src/test/ui/lifetime-errors/ex2a-push-one-existing-name.rs19
-rw-r--r--src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr27
-rw-r--r--src/test/ui/lifetime-errors/ex2b-push-no-existing-names.rs19
-rw-r--r--src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr27
-rw-r--r--src/test/ui/lifetime-errors/ex2c-push-inference-variable.rs20
-rw-r--r--src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr37
-rw-r--r--src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.rs21
-rw-r--r--src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr39
-rw-r--r--src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.rs21
-rw-r--r--src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr39
-rw-r--r--src/tools/linkchecker/main.rs24
-rw-r--r--src/tools/rustbook/Cargo.toml2
49 files changed, 483 insertions, 373 deletions
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<T>`. `Arc<T>` implements `Send` and `Sync` if and only if `T` implements
 both `Send` and `Sync`. For example, an object of type `Arc<RefCell<U>>` 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<RefCell<U>>` 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<T>` 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>`](#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<T>` 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>`](#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<Error>` 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<T, OurErrorType>`. In
 this case, `OurErrorType` is only `Box<Error>`. 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<T>`’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<T>`, so in this example `v` will have type
 `Vec<i32>`. 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<T>(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<T>(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<RegionResolutionError<'tcx>>)
-                      -> Option<Vec<RegionResolutionError<'tcx>>> {
+                      -> Vec<RegionResolutionError<'tcx>> {
         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();
-
-        // here we put errors that we will not be able to process nicely
-        let mut other_errors = Vec::new();
-
-        // 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<FreeRegionsFromSameFn> {
-            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
-                }
-            }
-        }
+        // 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.
+
+        let is_bound_failure = |e: &RegionResolutionError<'tcx>| match *e {
+            ConcreteFailure(..) => false,
+            SubSupConflict(..) => false,
+            GenericBoundFailure(..) => true,
+        };
 
-        fn append_to_same_regions(same_regions: &mut Vec<SameRegions>,
-                                  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<ProcessedErrorOrigin<'tcx>>,
-                    Vec<SameRegions>),
 }
 
 #[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<BoundRegion>,
-}
-
-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<TwoRegions<'tcx>, 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<Ref<'a, i32>>, y: Ref<i32>) {
+    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<Ref<'a, i32>>, y: Ref<i32>) {
+   |  ____________________________________________________^ 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<Ref<'a, i32>>, y: Ref<i32>) {
+   |  ____________________________________________________^ 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<Ref<i32>>, y: Ref<i32>) {
+    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<Ref<i32>>, y: Ref<i32>) {
+   |  ____________________________________________^ 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<Ref<i32>>, y: Ref<i32>) {
+   |  ____________________________________________^ 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<Ref<'b, i32>>, 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<Ref<'b, i32>>, 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<Ref<'b, i32>>, 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<Ref<'b, i32>>, y: Ref<'c, i32>) {
+    let a: &mut Vec<Ref<i32>> = 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<Ref<'b, i32>>, y: Ref<'c, i32>) {
+   |  ___________________________________________________________________^ starting here...
+16 | |     let a: &mut Vec<Ref<i32>> = 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<Ref<'b, i32>>, y: Ref<'c, i32>) {
+   |  ___________________________________________________________________^ starting here...
+16 | |     let a: &mut Vec<Ref<i32>> = 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<Ref<'_, i32>>, found &mut std::vec::Vec<Ref<'b, i32>>)
+  --> $DIR/ex2d-push-inference-variable-2.rs:16:33
+   |
+16 |     let a: &mut Vec<Ref<i32>> = 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<Ref<'b, i32>>, y: Ref<'c, i32>) {
+    let a: &mut Vec<Ref<i32>> = 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<Ref<'b, i32>>, y: Ref<'c, i32>) {
+   |  ___________________________________________________________________^ starting here...
+16 | |     let a: &mut Vec<Ref<i32>> = 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<Ref<'b, i32>>, y: Ref<'c, i32>) {
+   |  ___________________________________________________________________^ starting here...
+16 | |     let a: &mut Vec<Ref<i32>> = 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<Ref<'_, i32>>, found &mut std::vec::Vec<Ref<'b, i32>>)
+  --> $DIR/ex2e-push-inference-variable-3.rs:16:33
+   |
+16 |     let a: &mut Vec<Ref<i32>> = 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<String>,
+    names: HashSet<String>,
 }
 
 type Cache = HashMap<PathBuf, FileEntry>;
@@ -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