Skip to content

Commit a8d189a

Browse files
authored
Auto merge of #37170 - jonathandturner:rollup, r=jonathandturner
Rollup of 10 pull requests - Successful merges: #36307, #36755, #36961, #37102, #37115, #37119, #37122, #37123, #37141, #37159 - Failed merges:
2 parents 40cd1fd + 881f0f8 commit a8d189a

File tree

19 files changed

+283
-128
lines changed

19 files changed

+283
-128
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ build.
8989
$ pacman -S git \
9090
make \
9191
diffutils \
92+
tar \
9293
mingw-w64-x86_64-python2 \
9394
mingw-w64-x86_64-cmake \
9495
mingw-w64-x86_64-gcc

src/doc/book/lifetimes.md

+76-14
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,78 @@ complicated. For example, imagine this set of operations:
5050
4. You decide to use the resource.
5151

5252
Uh oh! Your reference is pointing to an invalid resource. This is called a
53-
dangling pointer or ‘use after free’, when the resource is memory.
53+
dangling pointer or ‘use after free’, when the resource is memory. A small
54+
example of such a situation would be:
55+
56+
```rust,compile_fail
57+
let r; // Introduce reference: r
58+
{
59+
let i = 1; // Introduce scoped value: i
60+
r = &i; // Store reference of i in r
61+
} // i goes out of scope and is dropped.
62+
63+
println!("{}", r); // r still refers to i
64+
```
5465

5566
To fix this, we have to make sure that step four never happens after step
56-
three. The ownership system in Rust does this through a concept called
57-
lifetimes, which describe the scope that a reference is valid for.
67+
three. In the small example above the Rust compiler is able to report the issue
68+
as it can see the lifetimes of the various values in the function.
69+
70+
When we have a function that takes arguments by reference the situation becomes
71+
more complex. Consider the following example:
72+
73+
```rust,compile_fail,E0106
74+
fn skip_prefix(line: &str, prefix: &str) -> &str {
75+
// ...
76+
# line
77+
}
78+
79+
let line = "lang:en=Hello World!";
80+
let lang = "en";
81+
82+
let v;
83+
{
84+
let p = format!("lang:{}=", lang); // -+ p goes into scope
85+
v = skip_prefix(line, p.as_str()); // |
86+
} // -+ p goes out of scope
87+
println!("{}", v);
88+
```
89+
90+
Here we have a function `skip_prefix` which takes two `&str` references
91+
as parameters and returns a single `&str` reference. We call it
92+
by passing in references to `line` and `p`: Two variables with different
93+
lifetimes. Now the safety of the `println!`-line depends on whether the
94+
reference returned by `skip_prefix` function references the still living
95+
`line` or the already dropped `p` string.
96+
97+
Because of the above ambiguity, Rust will refuse to compile the example
98+
code. To get it to compile we need to tell the compiler more about the
99+
lifetimes of the references. This can be done by making the lifetimes
100+
explicit in the function declaration:
101+
102+
```rust
103+
fn skip_prefix<'a, 'b>(line: &'a str, prefix: &'b str) -> &'a str {
104+
// ...
105+
# line
106+
}
107+
```
108+
109+
Let's examine the changes without going too deep into the syntax for now -
110+
we'll get to that later. The first change was adding the `<'a, 'b>` after the
111+
method name. This introduces two lifetime parameters: `'a` and `'b`. Next each
112+
reference in the function signature was associated with one of the lifetime
113+
parameters by adding the lifetime name after the `&`. This tells the compiler
114+
how the lifetimes between different references are related.
115+
116+
As a result the compiler is now able to deduce that the return value of
117+
`skip_prefix` has the same lifetime as the `line` parameter, which makes the `v`
118+
reference safe to use even after the `p` goes out of scope in the original
119+
example.
120+
121+
In addition to the compiler being able to validate the usage of `skip_prefix`
122+
return value, it can also ensure that the implementation follows the contract
123+
established by the function declaration. This is useful especially when you are
124+
implementing traits that are introduced [later in the book][traits].
58125

59126
**Note** It's important to understand that lifetime annotations are
60127
_descriptive_, not _prescriptive_. This means that how long a reference is valid
@@ -63,20 +130,14 @@ give information about lifetimes to the compiler that uses them to check the
63130
validity of references. The compiler can do so without annotations in simple
64131
cases, but needs the programmers support in complex scenarios.
65132

66-
```rust
67-
// implicit
68-
fn foo(x: &i32) {
69-
}
133+
[traits]: traits.html
70134

71-
// explicit
72-
fn bar<'a>(x: &'a i32) {
73-
}
74-
```
135+
# Syntax
75136

76137
The `'a` reads ‘the lifetime a’. Technically, every reference has some lifetime
77138
associated with it, but the compiler lets you elide (i.e. omit, see
78-
["Lifetime Elision"][lifetime-elision] below) them in common cases.
79-
Before we get to that, though, let’s break the explicit example down:
139+
["Lifetime Elision"][lifetime-elision] below) them in common cases. Before we
140+
get to that, though, let’s look at a short example with explicit lifetimes:
80141

81142
[lifetime-elision]: #lifetime-elision
82143

@@ -94,7 +155,8 @@ focus on the lifetimes aspect.
94155
[generics]: generics.html
95156

96157
We use `<>` to declare our lifetimes. This says that `bar` has one lifetime,
97-
`'a`. If we had two reference parameters, it would look like this:
158+
`'a`. If we had two reference parameters with different lifetimes, it would
159+
look like this:
98160

99161

100162
```rust,ignore

src/doc/book/type-aliases.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
% `type` Aliases
1+
% Type Aliases
22

33
The `type` keyword lets you declare an alias of another type:
44

src/libcore/hash/mod.rs

+22-15
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@
3838
//! ```
3939
//!
4040
//! If you need more control over how a value is hashed, you need to implement
41-
//! the `Hash` trait:
41+
//! the [`Hash`] trait:
42+
//!
43+
//! [`Hash`]: trait.Hash.html
4244
//!
4345
//! ```rust
4446
//! use std::hash::{Hash, Hasher, SipHasher};
@@ -90,21 +92,21 @@ mod sip;
9092
/// The `H` type parameter is an abstract hash state that is used by the `Hash`
9193
/// to compute the hash.
9294
///
93-
/// If you are also implementing `Eq`, there is an additional property that
95+
/// If you are also implementing [`Eq`], there is an additional property that
9496
/// is important:
9597
///
9698
/// ```text
9799
/// k1 == k2 -> hash(k1) == hash(k2)
98100
/// ```
99101
///
100102
/// In other words, if two keys are equal, their hashes should also be equal.
101-
/// `HashMap` and `HashSet` both rely on this behavior.
103+
/// [`HashMap`] and [`HashSet`] both rely on this behavior.
102104
///
103105
/// ## Derivable
104106
///
105107
/// This trait can be used with `#[derive]` if all fields implement `Hash`.
106108
/// When `derive`d, the resulting hash will be the combination of the values
107-
/// from calling `.hash()` on each field.
109+
/// from calling [`.hash()`] on each field.
108110
///
109111
/// ## How can I implement `Hash`?
110112
///
@@ -127,6 +129,11 @@ mod sip;
127129
/// }
128130
/// }
129131
/// ```
132+
///
133+
/// [`Eq`]: ../../std/cmp/trait.Eq.html
134+
/// [`HashMap`]: ../../std/collections/struct.HashMap.html
135+
/// [`HashSet`]: ../../std/collections/struct.HashSet.html
136+
/// [`.hash()`]: #tymethod.hash
130137
#[stable(feature = "rust1", since = "1.0.0")]
131138
pub trait Hash {
132139
/// Feeds this value into the state given, updating the hasher as necessary.
@@ -151,35 +158,35 @@ pub trait Hasher {
151158
#[stable(feature = "rust1", since = "1.0.0")]
152159
fn finish(&self) -> u64;
153160

154-
/// Writes some data into this `Hasher`
161+
/// Writes some data into this `Hasher`.
155162
#[stable(feature = "rust1", since = "1.0.0")]
156163
fn write(&mut self, bytes: &[u8]);
157164

158-
/// Write a single `u8` into this hasher
165+
/// Write a single `u8` into this hasher.
159166
#[inline]
160167
#[stable(feature = "hasher_write", since = "1.3.0")]
161168
fn write_u8(&mut self, i: u8) {
162169
self.write(&[i])
163170
}
164-
/// Write a single `u16` into this hasher.
171+
/// Writes a single `u16` into this hasher.
165172
#[inline]
166173
#[stable(feature = "hasher_write", since = "1.3.0")]
167174
fn write_u16(&mut self, i: u16) {
168175
self.write(&unsafe { mem::transmute::<_, [u8; 2]>(i) })
169176
}
170-
/// Write a single `u32` into this hasher.
177+
/// Writes a single `u32` into this hasher.
171178
#[inline]
172179
#[stable(feature = "hasher_write", since = "1.3.0")]
173180
fn write_u32(&mut self, i: u32) {
174181
self.write(&unsafe { mem::transmute::<_, [u8; 4]>(i) })
175182
}
176-
/// Write a single `u64` into this hasher.
183+
/// Writes a single `u64` into this hasher.
177184
#[inline]
178185
#[stable(feature = "hasher_write", since = "1.3.0")]
179186
fn write_u64(&mut self, i: u64) {
180187
self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i) })
181188
}
182-
/// Write a single `usize` into this hasher.
189+
/// Writes a single `usize` into this hasher.
183190
#[inline]
184191
#[stable(feature = "hasher_write", since = "1.3.0")]
185192
fn write_usize(&mut self, i: usize) {
@@ -189,31 +196,31 @@ pub trait Hasher {
189196
self.write(bytes);
190197
}
191198

192-
/// Write a single `i8` into this hasher.
199+
/// Writes a single `i8` into this hasher.
193200
#[inline]
194201
#[stable(feature = "hasher_write", since = "1.3.0")]
195202
fn write_i8(&mut self, i: i8) {
196203
self.write_u8(i as u8)
197204
}
198-
/// Write a single `i16` into this hasher.
205+
/// Writes a single `i16` into this hasher.
199206
#[inline]
200207
#[stable(feature = "hasher_write", since = "1.3.0")]
201208
fn write_i16(&mut self, i: i16) {
202209
self.write_u16(i as u16)
203210
}
204-
/// Write a single `i32` into this hasher.
211+
/// Writes a single `i32` into this hasher.
205212
#[inline]
206213
#[stable(feature = "hasher_write", since = "1.3.0")]
207214
fn write_i32(&mut self, i: i32) {
208215
self.write_u32(i as u32)
209216
}
210-
/// Write a single `i64` into this hasher.
217+
/// Writes a single `i64` into this hasher.
211218
#[inline]
212219
#[stable(feature = "hasher_write", since = "1.3.0")]
213220
fn write_i64(&mut self, i: i64) {
214221
self.write_u64(i as u64)
215222
}
216-
/// Write a single `isize` into this hasher.
223+
/// Writes a single `isize` into this hasher.
217224
#[inline]
218225
#[stable(feature = "hasher_write", since = "1.3.0")]
219226
fn write_isize(&mut self, i: isize) {

src/libcore/num/bignum.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,22 @@ use intrinsics;
3434
pub trait FullOps: Sized {
3535
/// Returns `(carry', v')` such that `carry' * 2^W + v' = self + other + carry`,
3636
/// where `W` is the number of bits in `Self`.
37-
fn full_add(self, other: Self, carry: bool) -> (bool /*carry*/, Self);
37+
fn full_add(self, other: Self, carry: bool) -> (bool /* carry */, Self);
3838

3939
/// Returns `(carry', v')` such that `carry' * 2^W + v' = self * other + carry`,
4040
/// where `W` is the number of bits in `Self`.
41-
fn full_mul(self, other: Self, carry: Self) -> (Self /*carry*/, Self);
41+
fn full_mul(self, other: Self, carry: Self) -> (Self /* carry */, Self);
4242

4343
/// Returns `(carry', v')` such that `carry' * 2^W + v' = self * other + other2 + carry`,
4444
/// where `W` is the number of bits in `Self`.
45-
fn full_mul_add(self, other: Self, other2: Self, carry: Self) -> (Self /*carry*/, Self);
45+
fn full_mul_add(self, other: Self, other2: Self, carry: Self) -> (Self /* carry */, Self);
4646

4747
/// Returns `(quo, rem)` such that `borrow * 2^W + self = quo * other + rem`
4848
/// and `0 <= rem < other`, where `W` is the number of bits in `Self`.
49-
fn full_div_rem(self, other: Self, borrow: Self) -> (Self /*quotient*/, Self /*remainder*/);
49+
fn full_div_rem(self,
50+
other: Self,
51+
borrow: Self)
52+
-> (Self /* quotient */, Self /* remainder */);
5053
}
5154

5255
macro_rules! impl_full_ops {
@@ -100,11 +103,7 @@ impl_full_ops! {
100103

101104
/// Table of powers of 5 representable in digits. Specifically, the largest {u8, u16, u32} value
102105
/// that's a power of five, plus the corresponding exponent. Used in `mul_pow5`.
103-
const SMALL_POW5: [(u64, usize); 3] = [
104-
(125, 3),
105-
(15625, 6),
106-
(1_220_703_125, 13),
107-
];
106+
const SMALL_POW5: [(u64, usize); 3] = [(125, 3), (15625, 6), (1_220_703_125, 13)];
108107

109108
macro_rules! define_bignum {
110109
($name:ident: type=$ty:ty, n=$n:expr) => (

src/libcore/num/diy_float.rs

+28-7
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,30 @@ impl Fp {
4949
pub fn normalize(&self) -> Fp {
5050
let mut f = self.f;
5151
let mut e = self.e;
52-
if f >> (64 - 32) == 0 { f <<= 32; e -= 32; }
53-
if f >> (64 - 16) == 0 { f <<= 16; e -= 16; }
54-
if f >> (64 - 8) == 0 { f <<= 8; e -= 8; }
55-
if f >> (64 - 4) == 0 { f <<= 4; e -= 4; }
56-
if f >> (64 - 2) == 0 { f <<= 2; e -= 2; }
57-
if f >> (64 - 1) == 0 { f <<= 1; e -= 1; }
52+
if f >> (64 - 32) == 0 {
53+
f <<= 32;
54+
e -= 32;
55+
}
56+
if f >> (64 - 16) == 0 {
57+
f <<= 16;
58+
e -= 16;
59+
}
60+
if f >> (64 - 8) == 0 {
61+
f <<= 8;
62+
e -= 8;
63+
}
64+
if f >> (64 - 4) == 0 {
65+
f <<= 4;
66+
e -= 4;
67+
}
68+
if f >> (64 - 2) == 0 {
69+
f <<= 2;
70+
e -= 2;
71+
}
72+
if f >> (64 - 1) == 0 {
73+
f <<= 1;
74+
e -= 1;
75+
}
5876
debug_assert!(f >= (1 >> 63));
5977
Fp { f: f, e: e }
6078
}
@@ -66,6 +84,9 @@ impl Fp {
6684
assert!(edelta >= 0);
6785
let edelta = edelta as usize;
6886
assert_eq!(self.f << edelta >> edelta, self.f);
69-
Fp { f: self.f << edelta, e: e }
87+
Fp {
88+
f: self.f << edelta,
89+
e: e,
90+
}
7091
}
7192
}

0 commit comments

Comments
 (0)