Skip to content

Commit 5e38627

Browse files
committed
Rust 1.15.1
1 parent 00ff49c commit 5e38627

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

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

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
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 (by Rust core team
28+
alum Huon Wilson no less - we need you now more than ever Huon!), and is a
29+
reminder that writing unsafe code is hard.
30+
31+
[discovered]: https://www.reddit.com/r/rust/comments/5roiq7/announcing_rust_115/dd8vujs/
32+
33+
`as_mut_slice` is a method on the `IntoIter` iterator for the `Vec` type that
34+
offers a mutable view into the buffer being iterated over. Conceptually it is
35+
simple: just return a reference to the buffer; and indeed the implementation is
36+
simple, but it's unsafe because `IntoIter` is implemented with an unsafe pointer
37+
to the buffer:
38+
39+
```rust
40+
pub fn as_mut_slice(&self) -> &mut [T] {
41+
unsafe {
42+
slice::from_raw_parts_mut(self.ptr as *mut T, self.len())
43+
}
44+
}
45+
```
46+
47+
It's just about the simplest unsafe method one could ask for. Can you spot the
48+
error? Our reviewers didn't! This method takes a shared reference and unsafely
49+
derives from it a mutable reference. That is totally bogus because it means
50+
`as_mut_slice` can be used to produce multiple mutable references to the same
51+
buffer, which is the one single thing you must not do in Rust.
52+
53+
Here's a simple example of what this bug would let you write, incorrectly:
54+
55+
```rust
56+
fn main() {
57+
let v = vec![0];
58+
let v_iter = v.into_iter();
59+
let slice1: &mut [_] = v_iter.as_mut_slice();
60+
let slice2: &mut [_] = v_iter.as_mut_slice();
61+
slice1[0] = 1;
62+
slice2[0] = 2;
63+
}
64+
```
65+
66+
Here both `slice1` and `slice2` are referencing the same mutable slice. Also
67+
notice that the iterator they are created from, `v_iter` is not declared
68+
mutable, which is a good indication something fishy is going on.
69+
70+
The [solution] here is trivial, just change `&self` to `&mut self`:
71+
72+
```rust
73+
pub fn as_mut_slice(&mut self) -> &mut [T] {
74+
unsafe {
75+
slice::from_raw_parts_mut(self.ptr as *mut T, self.len())
76+
}
77+
}
78+
```
79+
80+
[solution]: https://github.com/rust-lang/rust/pull/39466
81+
82+
With that, proper uniqueness invariants are maintained, only one mutable slice
83+
can be created at a time, and `v_iter` must be declared mutable in order to pull
84+
out a mutable slice.
85+
86+
So we made that change, and we're releasing a fix. In Rust we take pride in not
87+
breaking APIs, but since this is a new, minor feature, and the present
88+
implementation is spectacularly unsound, we decided to go ahead and release the
89+
fix immediately, hopefully before too many codebases pick it up - that is, we
90+
don't consider this a breaking change that requires a careful transition, but a
91+
necessary bug fix. For more about Rust's approach to ensuring stability see the
92+
["Stability as a Deliverable"][stab] blog post, [RFC 1122], on language
93+
evolution, and [RFC 1105], on library evolution (curiously, RFC 1105 does not
94+
actually contain any language allowing for library breakage due to soundness,
95+
but the intent has always been clear that Rust reserves the right to break code to
96+
fix soundness holes).
97+
98+
[stab]: https://blog.rust-lang.org/2014/10/30/Stability.html
99+
[RFC 1122]: https://github.com/rust-lang/rfcs/blob/master/text/1122-language-semver.md
100+
[RFC 1105]: https://github.com/rust-lang/rfcs/blob/master/text/1105-api-evolution.md
101+
102+
What can we learn from this? Well, it's at least good to be reminded why we
103+
endeavored to write a safe language in the first place: writing safe code is not
104+
easy. We have some ideas for how to catch this kind of problem earlier in the
105+
development process, but we haven't made any decisions yet.
106+
107+
We apologize for the inconvenience. Let's go hack.
108+
109+
### Contributors to 1.15.1
110+
111+
We had 2 individuals contribute to Rust 1.15.1.
112+
[Thanks!](https://thanks.rust-lang.org/rust/1.15.1)

0 commit comments

Comments
 (0)