Skip to content

Commit 37c49b9

Browse files
committed
Merge pull request #1 from aturon/1.9-edits
1.9 edits
2 parents 4bc066a + 4e928fd commit 37c49b9

File tree

1 file changed

+130
-84
lines changed

1 file changed

+130
-84
lines changed

_posts/2016-05-26-Rust-1.9.md

Lines changed: 130 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,10 @@ About 1400 patches were landed in this release.
1616

1717
### What's in 1.9 stable
1818

19-
Rust 1.9 contains some exciting new things!
19+
#### Controlled unwinding
2020

21-
First up, a new attribute for library authors: `#[deprecated]`. Authors of
22-
libraries can now tag items with this attribute, and users of their crate
23-
will see a warning when it is used. This new feature was defined in [RFC 1270].
24-
25-
[RFC 1270]: https://github.com/rust-lang/rfcs/blob/master/text/1270-deprecation.md
26-
27-
We now publishes std binaries for the `mips-unknown-linux-musl`,
28-
`mipsel-unknown-linux-musl`, and `i586-pc-windows-msvc` targets.
29-
30-
[The time complexity of comparing variables for equivalence][compare] during
31-
type unification is reduced from O(n!) to O(n). What does this mean? Certain
32-
kinds of code compiles much, much faster.
33-
34-
[compare]: https://github.com/rust-lang/rust/pull/32062
35-
36-
Strings are a very common type, and implement a lot of different traits.
37-
Specifically, when converting between `&str` and `String`, you have many
38-
options. Rustaceans used these two the most:
39-
40-
```rust
41-
let s = "some string".to_string();
42-
let s = "some string".to_owned();
43-
```
44-
45-
The former is the official convention, but it was discovered that it's not
46-
as fast as the second method. For a long time, it was not possible to improve
47-
this situation, however, a new language feature has landed on nightly and made
48-
this possible. [`libstd` now uses this internally][str] to make the two equivalent.
49-
50-
[str]: https://github.com/rust-lang/rust/pull/32586
51-
52-
Finally, this feature is technically a library change, but it's worth
53-
mentioning here as well. The `std::panic` module is being stabilized. This
54-
allows panics to be caught:
21+
The biggest shift in Rust 1.9 is the stabilization of the `std::panic` module,
22+
which includes methods for halting the unwinding process started by a panic:
5523

5624
```rust
5725
use std::panic;
@@ -67,83 +35,161 @@ let result = panic::catch_unwind(|| {
6735
assert!(result.is_err());
6836
```
6937

70-
This behavior was defined in [RFC 1236].
38+
This new API was defined in [RFC 1236].
7139

7240
[`std::panic`]: http://doc.rust-lang.org/stable/std/panic/index.html
7341
[RFC 1236]: https://github.com/rust-lang/rfcs/pull/1236
7442

75-
Historically, this has not been possible in Rust: panics are always
76-
unrecoverable. And in practice, this is still how they should be used. While
77-
the current implementation of `panic!` does unwinding, in a future release,
78-
crates will be able to choose a different implementation, namely, that
79-
`panic!` causes an abort, rather than unwind. Given that panics are for
80-
non-recoverable errors only, this is a valid implementation.
43+
In general, Rust distinguishes between two ways that an operation can fail:
44+
45+
- Due to an *expected problem*, like a file not being found.
46+
- Due to an *unexpected problem*, like an index being out of bounds for an array.
47+
48+
Expected problems usually arise from conditions that are outside of your
49+
control; robust code should be prepared for anything its environment might throw
50+
at it. In Rust, expected problems are handled via [the `Result` type][result],
51+
which allows a function to return information about the problem to its caller,
52+
which can then handle the error in a fine-grained way.
53+
54+
[result]: http://static.rust-lang.org/doc/master/std/result/index.html
55+
56+
Unexpected problems are *bugs*: they arise due to a contract or assertion being
57+
violated. Since they are unexpected, it doesn't make sense to handle them in a
58+
fine-grained way. Instead, Rust employs a "fail fast" approach by *panicking*,
59+
which by default unwinds the stack (running destructors but no other code) of
60+
the thread which discovered the error. Other threads continue running, but will
61+
discover the panic any time they try to communicate with the panicked thread
62+
(whether through channels or shared memory). Panics thus abort execution up to
63+
some "isolation boundary", with code on the other side of the boundary still
64+
able to run, and perhaps to "recover" from the panic in some very coarse-grained
65+
way. A server, for example, does not necessarily need to go down just because of
66+
an assertion failure in one of its threads.
8167

82-
If panics are for non-recoverable errors, why provide an interface for
83-
recovering from them? There are two big use-cases here:
68+
The new `catch_unwind` API offers a way to introduce new isolation boundaries
69+
*within a thread*. There are a couple of key motivating examples:
8470

8571
* Embedding Rust in other languages
8672
* Abstractions that manage threads
8773

8874
For the first case, unwinding across a language boundary is undefined behavior,
89-
and often leads to segfaults in practice. This means that when embedding Rust
90-
inside of other languages, you must avoid any code that can possibly panic, or
91-
rely on the (still unstable and only recently landed) 'abort' implementation of
92-
panic. Allowing panics to be caught at the language boundary provides more
93-
options in this case: an issue in Rust can return an error, rather than aborting
94-
the entire process. This is very important for many use-cases of embedding Rust;
95-
aborting is not always an acceptable option.
96-
97-
In the second, consider a threadpool library. If a thread panics, it's
98-
reasonable for the pool to not want to abort, but instead report the error,
99-
and, depending on the details, possibly even restart the thread, in an
100-
Erlang-style model. Recovering from these kinds of errors is very useful.
101-
102-
This change had a lot of discussion and thought put into it, by a large group
103-
of people. A significant worry about this change is that people may use it to
104-
try and emulate exceptions, which is not the intention of this functionality.
105-
However, the use-cases for this feature are legitimate, and there are two
106-
reasons we believe that this will not happen, generally:
107-
108-
* Rust already has a very strong culture of using `Result<T, E>` and `panic!`
109-
appropriately, and a new function will not change this culture overnight.
110-
* A significant part of Rust's userbase desires the abort implementation of
111-
panic, and libraries will need to work with both implementations.
75+
and often leads to segfaults in practice. Allowing panics to be caught means
76+
that you can safely expose Rust code via a C API, and translate unwinding into
77+
an error on the C side.
11278

113-
See the [detailed release notes][notes] for more.
79+
For the second case, consider a threadpool library. If a thread in the pool
80+
panics, you generally don't want to kill the thread itself, but rather catch the
81+
panic and communicate it to the client of the pool. The `catch_unwind` API is
82+
paired with `resume_unwind`, which can then be used to restart the panicking
83+
process on the client of the pool, where it belongs.
84+
85+
In both cases, you're introducing a new isolation boundary within a thread, and
86+
then translating the panic into some other form of error elsewhere.
87+
88+
A final point: why `catch_unwind` rather than `catch_panic`? We are
89+
[in the process][abort] of adding an additional strategy for panics: aborting
90+
the entire process (possibly after running a general [hook]). For some
91+
applications, this is the most reasonable way to deal with a programmer error,
92+
and avoiding unwinding can have performance and code size wins.
93+
94+
[hook]: https://github.com/rust-lang/rfcs/pull/1328
95+
[abort]: https://github.com/rust-lang/rfcs/pull/1513
96+
97+
#### Deprecation warnings
98+
99+
We introduced a new attribute for library authors: `#[deprecated]`. This attribute
100+
allows you to tag an API with a deprecation warning, which users of their crate
101+
will receive whenever they use the API, directing them to a replacement API.
102+
Deprecation warnings have long been a part of the standard library, but thanks
103+
to [RFC 1270] they're now usable ecosystem-wide.
104+
105+
[RFC 1270]: https://github.com/rust-lang/rfcs/blob/master/text/1270-deprecation.md
106+
107+
#### New targets
108+
109+
We now publish standard library binaries for several new targets:
110+
111+
- `mips-unknown-linux-musl`,
112+
- `mipsel-unknown-linux-musl`, and
113+
- `i586-pc-windows-msvc`.
114+
115+
The first two targets are particularly interesting from a cross-compilation
116+
perspective; see the [recent blog post on `rustup`][rustup] for more details.
117+
118+
[rustup]: http://blog.rust-lang.org/2016/05/13/rustup.html
119+
120+
#### Compile time improvements
121+
122+
[The time complexity of comparing variables for equivalence][compare] during
123+
type unification is reduced from O(n!) to O(n). As a result, some programming
124+
patterns compile much, much more quickly.
125+
126+
[compare]: https://github.com/rust-lang/rust/pull/32062
127+
128+
#### Rolling out use of specialization
129+
130+
This release sees some of the first use of [specialization] within the standard
131+
library. Specialization, which is currently available only on [nightly], allows
132+
generic code to automatically be specialized based on more specific type
133+
information.
134+
135+
One example where this comes up in the standard library: conversion from a
136+
string slice (`&str`) to an owned `String`. One method, `to_string`, comes from
137+
a generic API which was previously relatively slow, while the custom `to_owned`
138+
implementation provided better performance. Using specialization, these two
139+
functions are [now equivalent].
140+
141+
With this simple test of specialization under our belt, we have more performance
142+
improvements on the way in upcoming releases.
143+
144+
[specialization]: https://github.com/rust-lang/rfcs/pull/1210
145+
[nightly]: http://blog.rust-lang.org/2014/10/30/Stability.html
146+
[now equivalent]: https://github.com/rust-lang/rust/pull/32586
114147

115148
#### Library stabilizations
116149

117-
About 80 library functions and methods are now stable in 1.8. Lots of stuff!
118-
The most major is the `std::panic` module, described in the previous section,
119-
but there's a lot more too:
150+
About 80 library functions and methods are now stable in 1.9. The most major is
151+
the `std::panic` module, described earlier, but there's a lot more too:
152+
153+
**Networking**
154+
155+
* `TcpStream`, `TcpListener`, and `UdpSocket` gained a number of methods for
156+
configuring the connection.
157+
* `SocketAddr` and its variants gained `set_ip()` and `set_port()` conveniences.
158+
159+
**Collections**
160+
161+
* `BTreeSet` and `HashSet` gained the `take()`, `replace()`, and `get()`
162+
methods, which make it possible to recover ownership of the original key.
163+
* `OsString` gained a few methods, bringing it closer to parity with `String`.
164+
* Slices gained `copy_from_slice()`, a safe form of `memcpy`.
165+
166+
**Encoding**
120167

121-
* Raw pointers gained `as_ref()` and `as_mut()`, which returns an `Option<&T>`.
122168
* `char` gained the ability to decode into UTF-16.
123-
* `BTreeSet` and `HashSet` gained the `take()`, `replace()`, and `get()` methods.
124-
* `OsString` gained some methods to bring it up to parity with `String`.
125-
* `SocketAddr` and its variants gained `set_ip()` and `set_port()`.
126-
* Slices gained `copy_from_slice()`, a way to efficiently copy a slice.
169+
170+
**Pointers**
171+
172+
* Raw pointers gained `as_ref()` and `as_mut()`, which returns an `Option<&T>`,
173+
translating null pointers into `None`.
127174
* `ptr::{read,write}_volitile()` allow for volitile reading and writing from a
128175
raw pointer.
129-
* `TcpStream`, `TcpListener`, and `UdpSocket` gained a number of methods that
130-
let you set various aspects of the connection.
131176

132177
Finally, many of the types in `libcore` did not contain a `Debug`
133-
implementation. [This was fixed](https://github.com/rust-lang/rust/pull/32054).
178+
implementation. [This was fixed](https://github.com/rust-lang/rust/pull/32054)
179+
in the 1.9 release.
134180

135181
See the [detailed release notes][notes] for more.
136182

137183
#### Cargo features
138184

139185
There were two major changes to Cargo:
140186

141-
First, Cargo has historically not been able to be run concurrently. [This has
142-
been fixed](https://github.com/rust-lang/cargo/pull/2486).
187+
First, Cargo
188+
[can now be run concurrently](https://github.com/rust-lang/cargo/pull/2486).
143189

144-
Second, a new flag, `RUSTFLAGS`, [was
145-
added](https://github.com/rust-lang/cargo/pull/2241). This allows you to
146-
specify arbitrary flags to be passed to `rustc` through an environment
190+
Second, a new flag, `RUSTFLAGS`,
191+
[was added](https://github.com/rust-lang/cargo/pull/2241). This flag allows you
192+
to specify arbitrary flags to be passed to `rustc` through an environment
147193
variable, which is useful for packagers, for example.
148194

149195
See the [detailed release notes][notes] for more.

0 commit comments

Comments
 (0)