Skip to content

Commit e7e85d9

Browse files
committed
Rust 1.15.1
1 parent 00ff49c commit e7e85d9

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

_posts/2017-02-08-Rust-1.15.1.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
---
2+
layout: post
3+
title: "Announcing Rust 1.15.1"
4+
author: The Rust Core Team
5+
---
6+
7+
The Rust team is happy to announce the latest version of Rust, 1.15.1. Rust is a
8+
systems programming language focused on safety, speed, and concurrency.
9+
10+
If you have a previous version of Rust installed, getting Rust 1.15.1 is as easy as:
11+
12+
```bash
13+
$ rustup update stable
14+
```
15+
16+
If you don't have it already, you can [download Rust][install] from the
17+
appropriate page on our website, and check out the [detailed release notes for
18+
1.15.1][notes] on GitHub.
19+
20+
[install]: https://www.rust-lang.org/install.html
21+
[notes]: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1151-2017-02-08
22+
23+
### What's in 1.15.1 stable
24+
25+
This release fixes a single issue, a soundness bug in the new
26+
`vec::IntoIter::as_mut_slice` method. The problem with this three line function
27+
was [discovered] just minutes after publishing Rust 1.15.0, and is a reminder
28+
that writing unsafe code is hard.
29+
30+
[discovered]: https://www.reddit.com/r/rust/comments/5roiq7/announcing_rust_115/dd8vujs/
31+
32+
`as_mut_slice` is a method on the `IntoIter` iterator for the `Vec` type that
33+
offers a mutable view into the buffer being iterated over. Conceptually it is
34+
simple: just return a reference to the buffer; and indeed the implementation is
35+
simple, but it's unsafe because `IntoIter` is implemented with an unsafe pointer
36+
to the buffer:
37+
38+
```rust
39+
pub fn as_mut_slice(&self) -> &mut [T] {
40+
unsafe {
41+
slice::from_raw_parts_mut(self.ptr as *mut T, self.len())
42+
}
43+
}
44+
```
45+
46+
It's just about the simplest unsafe method one could ask for. Can you spot the
47+
error? Our reviewers didn't! This API slipped through the cracks because it is
48+
such a standard and small one. It's a copy-paste bug that the reviewers glossed
49+
over. This method takes a shared reference and unsafely derives from it a
50+
mutable reference. That is totally bogus because it means `as_mut_slice` can be
51+
used to produce multiple mutable references to the same buffer, which is the one
52+
single thing you must not do in Rust.
53+
54+
Here's a simple example of what this bug would let you write, incorrectly:
55+
56+
```rust
57+
fn main() {
58+
let v = vec![0];
59+
let v_iter = v.into_iter();
60+
let slice1: &mut [_] = v_iter.as_mut_slice();
61+
let slice2: &mut [_] = v_iter.as_mut_slice();
62+
slice1[0] = 1;
63+
slice2[0] = 2;
64+
}
65+
```
66+
67+
Here both `slice1` and `slice2` are referencing the same mutable slice. Also
68+
notice that the iterator they are created from, `v_iter` is not declared
69+
mutable, which is a good indication something fishy is going on.
70+
71+
The [solution] here is trivial, just change `&self` to `&mut self`:
72+
73+
```rust
74+
pub fn as_mut_slice(&mut self) -> &mut [T] {
75+
unsafe {
76+
slice::from_raw_parts_mut(self.ptr as *mut T, self.len())
77+
}
78+
}
79+
```
80+
81+
[solution]: https://github.com/rust-lang/rust/pull/39466
82+
83+
With that, proper uniqueness invariants are maintained, only one mutable slice
84+
can be created at a time, and `v_iter` must be declared mutable in order to pull
85+
out a mutable slice.
86+
87+
So we made that change, and we're releasing a fix. In Rust we take pride in not
88+
breaking APIs, but since this is a new, minor feature, and the present
89+
implementation is spectacularly unsound, we decided to go ahead and release the
90+
fix immediately, hopefully before too many codebases pick it up - that is, we
91+
don't consider this a breaking change that requires a careful transition, but a
92+
necessary bug fix. For more about Rust's approach to ensuring stability see the
93+
["Stability as a Deliverable"][stab] blog post, [RFC 1122], on language
94+
evolution, and [RFC 1105], on library evolution (curiously, RFC 1105 does not
95+
actually contain any language allowing for library breakage due to soundness,
96+
but the intent has always been clear that Rust reserves the right to break code to
97+
fix soundness holes).
98+
99+
[stab]: https://blog.rust-lang.org/2014/10/30/Stability.html
100+
[RFC 1122]: https://github.com/rust-lang/rfcs/blob/master/text/1122-language-semver.md
101+
[RFC 1105]: https://github.com/rust-lang/rfcs/blob/master/text/1105-api-evolution.md
102+
103+
What can we learn from this? Well, it's at least good to be reminded why we
104+
endeavored to write a safe language in the first place: writing safe code is not
105+
easy. We have some ideas for how to catch this kind of problem earlier in the
106+
development process, but we haven't made any decisions yet.
107+
108+
We apologize for the inconvenience. Let's go hack.
109+
110+
### Contributors to 1.15.1
111+
112+
We had 2 individuals contribute to Rust 1.15.1.
113+
[Thanks!](https://thanks.rust-lang.org/rust/1.15.1)

0 commit comments

Comments
 (0)