Auto merge of #39981 - frewsxcv:rollup, r=frewsxcv

Rollup of 3 pull requests

- Successful merges: #39913, #39937, #39976
- Failed merges:
This commit is contained in:
bors 2017-02-20 18:58:28 +00:00
commit c1368fc4f4
49 changed files with 482 additions and 372 deletions

6
src/Cargo.lock generated
View File

@ -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"

View File

@ -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

View File

@ -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) doesnt kick in here. Then what
[elision](lifetimes.html#lifetime-elision) doesnt kick in here. Then what
choices do we have? Try `'static`:
```rust,ignore

View File

@ -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:

View File

@ -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

View File

@ -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`?

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -119,7 +119,7 @@ there are no arguments, and `{` starts the body of the function. Because
we didnt include a return type, its 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 weve chosen `u32`. Its 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👍%`? Thered be no way to convert that to a number. As

View File

@ -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, lets look at a short example with explicit lifetimes:
[lifetime-elision]: #Lifetime%20Elision
[lifetime-elision]: #lifetime-elision
```rust,ignore
fn bar<'a>(...)

View File

@ -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
Rusts 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

View File

@ -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, thats 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

View File

@ -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:

View File

@ -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)

View File

@ -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

View File

@ -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) {

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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
///

View File

@ -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")]

View File

@ -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.
///

View File

@ -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

View File

@ -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();
// 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<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
}
}
}
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> {

View File

@ -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> {

View File

@ -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.
//

View File

@ -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

View File

@ -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
///

View File

@ -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
}
}

View File

@ -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];

View File

@ -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() { }

View File

@ -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

View File

@ -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() { }

View File

@ -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

View File

@ -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() { }

View File

@ -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

View File

@ -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() { }

View File

@ -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

View File

@ -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() { }

View File

@ -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

View File

@ -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() { }

View File

@ -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

View File

@ -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() { }

View File

@ -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

View File

@ -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

View File

@ -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