Skip to content

Commit 8dd8fed

Browse files
committed
---
yaml --- r: 236091 b: refs/heads/stable c: 7aee844 h: refs/heads/master i: 236089: c696a98 236087: ab71ad9 v: v3
1 parent 3a40398 commit 8dd8fed

27 files changed

+177
-122
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ refs/heads/tmp: afae2ff723393b3ab4ccffef6ac7c6d1809e2da0
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: f859507de8c410b648d934d8f5ec1c52daac971d
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: 58f6f2d57a4d0a62f17003facd0d2406da75a035
32+
refs/heads/stable: 7aee8448ea461a598075065491e98f941a570fea
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b
3535
refs/tags/1.2.0: f557861f822c34f07270347b94b5280de20a597e

branches/stable/src/doc/tarpl/checked-uninit.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Like C, all stack variables in Rust are uninitialized until a value is
44
explicitly assigned to them. Unlike C, Rust statically prevents you from ever
55
reading them until you do:
66

7-
```rust
7+
```rust,ignore
88
fn main() {
99
let x: i32;
1010
println!("{}", x);
@@ -39,7 +39,7 @@ fn main() {
3939

4040
but this doesn't:
4141

42-
```rust
42+
```rust,ignore
4343
fn main() {
4444
let x: i32;
4545
if true {

branches/stable/src/doc/tarpl/coercions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ receivers, see below). If there is an impl for some type `U` and `T` coerces to
5151
following will not type check, even though it is OK to coerce `t` to `&T` and
5252
there is an impl for `&T`:
5353

54-
```rust
54+
```rust,ignore
5555
trait Trait {}
5656
5757
fn foo<X: Trait>(t: X) {}

branches/stable/src/doc/tarpl/destructors.md

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
What the language *does* provide is full-blown automatic destructors through the
44
`Drop` trait, which provides the following method:
55

6-
```rust
6+
```rust,ignore
77
fn drop(&mut self);
88
```
99

@@ -23,13 +23,22 @@ this is totally fine.
2323
For instance, a custom implementation of `Box` might write `Drop` like this:
2424

2525
```rust
26-
struct Box<T>{ ptr: *mut T }
26+
#![feature(heap_api, core_intrinsics, unique)]
27+
28+
use std::rt::heap;
29+
use std::ptr::Unique;
30+
use std::intrinsics::drop_in_place;
31+
use std::mem;
32+
33+
struct Box<T>{ ptr: Unique<T> }
2734

2835
impl<T> Drop for Box<T> {
2936
fn drop(&mut self) {
3037
unsafe {
31-
(*self.ptr).drop();
32-
heap::deallocate(self.ptr);
38+
drop_in_place(*self.ptr);
39+
heap::deallocate((*self.ptr) as *mut u8,
40+
mem::size_of::<T>(),
41+
mem::align_of::<T>());
3342
}
3443
}
3544
}
@@ -42,25 +51,36 @@ after-free the `ptr` because the Box is immediately marked as uninitialized.
4251
However this wouldn't work:
4352

4453
```rust
45-
struct Box<T>{ ptr: *mut T }
54+
#![feature(heap_api, core_intrinsics, unique)]
55+
56+
use std::rt::heap;
57+
use std::ptr::Unique;
58+
use std::intrinsics::drop_in_place;
59+
use std::mem;
60+
61+
struct Box<T>{ ptr: Unique<T> }
4662

4763
impl<T> Drop for Box<T> {
4864
fn drop(&mut self) {
4965
unsafe {
50-
(*self.ptr).drop();
51-
heap::deallocate(self.ptr);
66+
drop_in_place(*self.ptr);
67+
heap::deallocate((*self.ptr) as *mut u8,
68+
mem::size_of::<T>(),
69+
mem::align_of::<T>());
5270
}
5371
}
5472
}
5573

56-
struct SuperBox<T> { box: Box<T> }
74+
struct SuperBox<T> { my_box: Box<T> }
5775

5876
impl<T> Drop for SuperBox<T> {
5977
fn drop(&mut self) {
6078
unsafe {
6179
// Hyper-optimized: deallocate the box's contents for it
6280
// without `drop`ing the contents
63-
heap::deallocate(self.box.ptr);
81+
heap::deallocate((*self.my_box.ptr) as *mut u8,
82+
mem::size_of::<T>(),
83+
mem::align_of::<T>());
6484
}
6585
}
6686
}
@@ -106,26 +126,39 @@ The classic safe solution to overriding recursive drop and allowing moving out
106126
of Self during `drop` is to use an Option:
107127

108128
```rust
109-
struct Box<T>{ ptr: *mut T }
129+
#![feature(heap_api, core_intrinsics, unique)]
130+
131+
use std::rt::heap;
132+
use std::ptr::Unique;
133+
use std::intrinsics::drop_in_place;
134+
use std::mem;
135+
136+
struct Box<T>{ ptr: Unique<T> }
110137

111138
impl<T> Drop for Box<T> {
112139
fn drop(&mut self) {
113140
unsafe {
114-
(*self.ptr).drop();
115-
heap::deallocate(self.ptr);
141+
drop_in_place(*self.ptr);
142+
heap::deallocate((*self.ptr) as *mut u8,
143+
mem::size_of::<T>(),
144+
mem::align_of::<T>());
116145
}
117146
}
118147
}
119148

120-
struct SuperBox<T> { box: Option<Box<T>> }
149+
struct SuperBox<T> { my_box: Option<Box<T>> }
121150

122151
impl<T> Drop for SuperBox<T> {
123152
fn drop(&mut self) {
124153
unsafe {
125154
// Hyper-optimized: deallocate the box's contents for it
126155
// without `drop`ing the contents. Need to set the `box`
127156
// field as `None` to prevent Rust from trying to Drop it.
128-
heap::deallocate(self.box.take().unwrap().ptr);
157+
let my_box = self.my_box.take().unwrap();
158+
heap::deallocate((*my_box.ptr) as *mut u8,
159+
mem::size_of::<T>(),
160+
mem::align_of::<T>());
161+
mem::forget(my_box);
129162
}
130163
}
131164
}

branches/stable/src/doc/tarpl/drop-flags.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ And even branched code where all branches have the same behaviour with respect
3131
to initialization:
3232

3333
```rust
34+
# let condition = true;
3435
let mut x = Box::new(0); // x was uninit; just overwrite.
3536
if condition {
3637
drop(x) // x gets moved out; make x uninit.
@@ -45,6 +46,7 @@ x = Box::new(0); // x was uninit; just overwrite.
4546
However code like this *requires* runtime information to correctly Drop:
4647

4748
```rust
49+
# let condition = true;
4850
let x;
4951
if condition {
5052
x = Box::new(0); // x was uninit; just overwrite.
@@ -56,6 +58,7 @@ if condition {
5658
Of course, in this case it's trivial to retrieve static drop semantics:
5759

5860
```rust
61+
# let condition = true;
5962
if condition {
6063
let x = Box::new(0);
6164
println!("{}", x);

branches/stable/src/doc/tarpl/exception-safety.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ way to do this is to store the algorithm's state in a separate struct with a
156156
destructor for the "finally" logic. Whether we panic or not, that destructor
157157
will run and clean up after us.
158158

159-
```rust
159+
```rust,ignore
160160
struct Hole<'a, T: 'a> {
161161
data: &'a mut [T],
162162
/// `elt` is always `Some` from new until drop.

branches/stable/src/doc/tarpl/hrtb.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ fn main() {
2828
If we try to naively desugar this code in the same way that we did in the
2929
lifetimes section, we run into some trouble:
3030

31-
```rust
31+
```rust,ignore
3232
struct Closure<F> {
3333
data: (u8, u16),
3434
func: F,
@@ -60,7 +60,7 @@ we enter the body of `call`! Also, that isn't some fixed lifetime; call works wi
6060
This job requires The Magic of Higher-Rank Trait Bounds. The way we desugar
6161
this is as follows:
6262

63-
```rust
63+
```rust,ignore
6464
where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8,
6565
```
6666

@@ -69,4 +69,4 @@ where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8,
6969
`for<'a>` can be read as "for all choices of `'a`", and basically produces an
7070
*inifinite list* of trait bounds that F must satisfy. Intense. There aren't many
7171
places outside of the Fn traits where we encounter HRTBs, and even for those we
72-
have a nice magic sugar for the common cases.
72+
have a nice magic sugar for the common cases.

branches/stable/src/doc/tarpl/leaking.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ unwinding-safe! Easy!
6868

6969
Now consider the following:
7070

71-
```
71+
```rust,ignore
7272
let mut vec = vec![Box::new(0); 4];
7373
7474
{
@@ -118,7 +118,7 @@ Nope.
118118

119119
Let's consider a simplified implementation of Rc:
120120

121-
```rust
121+
```rust,ignore
122122
struct Rc<T> {
123123
ptr: *mut RcBox<T>,
124124
}
@@ -183,7 +183,7 @@ in memory.
183183
The thread::scoped API intends to allow threads to be spawned that reference
184184
data on the stack without any synchronization over that data. Usage looked like:
185185

186-
```rust
186+
```rust,ignore
187187
let mut data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
188188
{
189189
let guards = vec![];
@@ -211,7 +211,7 @@ let mut data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
211211
In principle, this totally works! Rust's ownership system perfectly ensures it!
212212
...except it relies on a destructor being called to be safe.
213213

214-
```
214+
```rust,ignore
215215
let mut data = Box::new(0);
216216
{
217217
let guard = thread::scoped(|| {

branches/stable/src/doc/tarpl/lifetime-elision.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ In order to make common patterns more ergonomic, Rust allows lifetimes to be
55

66
A *lifetime position* is anywhere you can write a lifetime in a type:
77

8-
```rust
8+
```rust,ignore
99
&'a T
1010
&'a mut T
1111
T<'a>
@@ -38,7 +38,7 @@ Elision rules are as follows:
3838

3939
Examples:
4040

41-
```rust
41+
```rust,ignore
4242
fn print(s: &str); // elided
4343
fn print<'a>(s: &'a str); // expanded
4444
@@ -61,4 +61,4 @@ fn args<'a, 'b, T:ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command // exp
6161
fn new(buf: &mut [u8]) -> BufWriter; // elided
6262
fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> // expanded
6363
64-
```
64+
```

branches/stable/src/doc/tarpl/lifetime-misc.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ types or lifetimes are logically associated with a struct, but not actually
1010
part of a field. This most commonly occurs with lifetimes. For instance, the `Iter`
1111
for `&'a [T]` is (approximately) defined as follows:
1212

13-
```rust
14-
pub struct Iter<'a, T: 'a> {
13+
```rust,ignore
14+
struct Iter<'a, T: 'a> {
1515
ptr: *const T,
1616
end: *const T,
1717
}
@@ -33,7 +33,9 @@ Iter logically contains `&'a T`, so this is exactly what we tell
3333
the PhantomData to simulate:
3434

3535
```
36-
pub struct Iter<'a, T: 'a> {
36+
use std::marker;
37+
38+
struct Iter<'a, T: 'a> {
3739
ptr: *const T,
3840
end: *const T,
3941
_marker: marker::PhantomData<&'a T>,
@@ -68,6 +70,8 @@ tell dropck that we *do* own values of type T, and may call destructors of that
6870
type, we must add extra PhantomData:
6971

7072
```
73+
use std::marker;
74+
7175
struct Vec<T> {
7276
data: *const T, // *const for covariance!
7377
len: usize,
@@ -115,7 +119,7 @@ println!("{} {} {} {}", a, b, c, c2);
115119
However borrowck doesn't understand arrays or slices in any way, so this doesn't
116120
work:
117121

118-
```rust
122+
```rust,ignore
119123
let x = [1, 2, 3];
120124
let a = &mut x[0];
121125
let b = &mut x[1];
@@ -144,7 +148,7 @@ left of the index, and one for everything to the right. Intuitively we know this
144148
is safe because the slices don't alias. However the implementation requires some
145149
unsafety:
146150

147-
```rust
151+
```rust,ignore
148152
fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
149153
unsafe {
150154
let self2: &mut [T] = mem::transmute_copy(&self);
@@ -189,8 +193,8 @@ Whether it's raw pointers, or safely composing on top of *another* IterMut.
189193

190194
For instance, VecDeque's IterMut:
191195

192-
```rust
193-
pub struct IterMut<'a, T:'a> {
196+
```rust,ignore
197+
struct IterMut<'a, T:'a> {
194198
// The whole backing array. Some of these indices are initialized!
195199
ring: &'a mut [T],
196200
tail: usize,

branches/stable/src/doc/tarpl/lifetimes.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ let z = &y;
3838
The borrow checker always tries to minimize the extent of a lifetime, so it will
3939
likely desugar to the following:
4040

41-
```rust
41+
```rust,ignore
4242
// NOTE: `'a: {` and `&'b x` is not valid syntax!
4343
'a: {
4444
let x: i32 = 0;
@@ -69,8 +69,8 @@ z = y;
6969
The borrow checker always tries to minimize the extent of a lifetime, so it will
7070
likely desugar to something like the following:
7171

72-
```rust
73-
// NOTE: `'a: {` and `&'b x` is not valid syntax!
72+
```rust,ignore
73+
// NOTE: `'a: {` and `foo = &'b x` is not valid syntax!
7474
'a: {
7575
let x: i32 = 0;
7676
'b: {
@@ -174,14 +174,14 @@ our implementation *just a bit*.)
174174

175175
How about the other example:
176176

177-
```rust
177+
```rust,ignore
178178
let mut data = vec![1, 2, 3];
179179
let x = &data[0];
180180
data.push(4);
181181
println!("{}", x);
182182
```
183183

184-
```rust
184+
```rust,ignore
185185
'a: {
186186
let mut data: Vec<i32> = vec![1, 2, 3];
187187
'b: {
@@ -219,4 +219,4 @@ semantics we're actually interested in preserving. For the most part, *that's
219219
totally ok*, because it keeps us from spending all day explaining our program
220220
to the compiler. However it does mean that several programs that are *totally*
221221
correct with respect to Rust's *true* semantics are rejected because lifetimes
222-
are too dumb.
222+
are too dumb.

branches/stable/src/doc/tarpl/ownership.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ issue...). This is a pervasive problem that C and C++ need to deal with.
1616
Consider this simple mistake that all of us who have used a non-GC'd language
1717
have made at one point:
1818

19-
```rust
19+
```rust,ignore
2020
fn as_str(data: &u32) -> &str {
2121
// compute the string
2222
let s = format!("{}", data);
@@ -45,7 +45,7 @@ verifying that references don't escape the scope of their referent. That's
4545
because ensuring pointers are always valid is much more complicated than this.
4646
For instance in this code,
4747

48-
```rust
48+
```rust,ignore
4949
let mut data = vec![1, 2, 3];
5050
// get an internal reference
5151
let x = &data[0];

0 commit comments

Comments
 (0)