@@ -16,42 +16,10 @@ About 1400 patches were landed in this release.
16
16
17
17
### What's in 1.9 stable
18
18
19
- Rust 1.9 contains some exciting new things!
19
+ #### Controlled unwinding
20
20
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:
55
23
56
24
``` rust
57
25
use std :: panic;
@@ -67,83 +35,161 @@ let result = panic::catch_unwind(|| {
67
35
assert! (result . is_err ());
68
36
```
69
37
70
- This behavior was defined in [ RFC 1236] .
38
+ This new API was defined in [ RFC 1236] .
71
39
72
40
[ `std::panic` ] : http://doc.rust-lang.org/stable/std/panic/index.html
73
41
[ RFC 1236 ] : https://github.com/rust-lang/rfcs/pull/1236
74
42
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.
81
67
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 :
84
70
85
71
* Embedding Rust in other languages
86
72
* Abstractions that manage threads
87
73
88
74
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.
112
78
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
114
147
115
148
#### Library stabilizations
116
149
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**
120
167
121
- * Raw pointers gained ` as_ref() ` and ` as_mut() ` , which returns an ` Option<&T> ` .
122
168
* ` 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 ` .
127
174
* ` ptr::{read,write}_volitile() ` allow for volitile reading and writing from a
128
175
raw pointer.
129
- * ` TcpStream ` , ` TcpListener ` , and ` UdpSocket ` gained a number of methods that
130
- let you set various aspects of the connection.
131
176
132
177
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.
134
180
135
181
See the [ detailed release notes] [ notes ] for more.
136
182
137
183
#### Cargo features
138
184
139
185
There were two major changes to Cargo:
140
186
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 ) .
143
189
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
147
193
variable, which is useful for packagers, for example.
148
194
149
195
See the [ detailed release notes] [ notes ] for more.
0 commit comments