Skip to content

Commit d42e013

Browse files
authored
Merge pull request #192 from rust-lang/1.20-announcement
Rust 1.20.0 release post
2 parents e11ca98 + f2d1aba commit d42e013

File tree

1 file changed

+304
-0
lines changed

1 file changed

+304
-0
lines changed

_posts/2017-08-31-Rust-1.20.md

+304
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
---
2+
layout: post
3+
title: "Announcing Rust 1.20"
4+
author: The Rust Core Team
5+
---
6+
7+
The Rust team is happy to announce the latest version of Rust, 1.20.0. Rust
8+
is a systems programming language focused on safety, speed, and concurrency.
9+
10+
If you have a previous version of Rust installed, getting Rust 1.20 is as easy as:
11+
12+
```bash
13+
$ rustup update stable
14+
```
15+
16+
If you don't have it already, you can [get `rustup`][install] from the
17+
appropriate page on our website, and check out the [detailed release notes for
18+
1.20.0][notes] on GitHub. 1443 patches were landed in this release.
19+
20+
[install]: https://www.rust-lang.org/install.html
21+
[notes]: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1200-2017-08-31
22+
23+
### What's in 1.20.0 stable
24+
25+
In Rust, you can already define traits, structs, and enums that have "associated functions":
26+
27+
```rust
28+
struct Struct;
29+
30+
impl Struct {
31+
fn foo() {
32+
println!("foo is an associated function of Struct");
33+
}
34+
}
35+
36+
fn main() {
37+
Struct::foo();
38+
}
39+
```
40+
41+
These are called "associated functions" because they are functions that are
42+
associated with the type, that is, they're attached to the type itself, and
43+
not any particular instance.
44+
45+
Rust 1.20 adds the ability to define "associated constants" as well:
46+
47+
```rust
48+
struct Struct;
49+
50+
impl Struct {
51+
const ID: u32 = 0;
52+
}
53+
54+
fn main() {
55+
println!("the ID of Struct is: {}", Struct::ID);
56+
}
57+
```
58+
59+
That is, the constant `ID` is associated with `Struct`. Like functions,
60+
associated constants work with traits and enums as well.
61+
62+
Traits have an extra ability with associated constants that gives them some
63+
extra power. With a trait, you can use an associated constant in the same way
64+
you'd use an associated type: by declaring it, but not giving it a value. The
65+
implementor of the trait then declares its value upon implementation:
66+
67+
```rust
68+
trait Trait {
69+
const ID: u32;
70+
}
71+
72+
struct Struct;
73+
74+
impl Trait for Struct {
75+
const ID: u32 = 5;
76+
}
77+
78+
fn main() {
79+
println!("{}", Struct::ID);
80+
}
81+
```
82+
83+
Before this release, if you wanted to make a trait that represented floating
84+
point numbers, you'd have to write this:
85+
86+
```rust
87+
trait Float {
88+
fn nan() -> Self;
89+
fn infinity() -> Self;
90+
...
91+
}
92+
```
93+
94+
This is slightly unweildy, but more importantly, becuase they're functions, they
95+
cannot be used in constant expressions, even though they only return a constant.
96+
Because of this, a design for `Float` would also have to include constants as well:
97+
98+
```rust
99+
mod f32 {
100+
const NAN: f32 = 0.0f32 / 0.0f32;
101+
const INFINITY: f32 = 1.0f32 / 0.0f32;
102+
103+
impl Float for f32 {
104+
fn nan() -> Self {
105+
f32::NAN
106+
}
107+
fn infinity() -> Self {
108+
f32::INFINITY
109+
}
110+
}
111+
}
112+
```
113+
114+
Associated constants let you do this in a much cleaner way. This trait definition:
115+
116+
```rust
117+
trait Float {
118+
const NAN: Self;
119+
const INFINITY: Self;
120+
...
121+
}
122+
```
123+
124+
Leads to this implementation:
125+
126+
```rust
127+
mod f32 {
128+
impl Float for f32 {
129+
const NAN: f32 = 0.0f32 / 0.0f32;
130+
const INFINITY: f32 = 1.0f32 / 0.0f32;
131+
}
132+
}
133+
```
134+
135+
much cleaner, and more versatile.
136+
137+
Associated constants were proposed in [RFC 195], almost exactly three years ago. It's
138+
been quite a while for this feature! That RFC contained all associated items, not just
139+
constants, and so some of them, such as associated types, were implemented faster than
140+
others. In general, we've been doing a lot of internal work for constant evaluation,
141+
to increase Rust's capabilities for compile-time metaprogramming. Expect more on this
142+
front in the future.
143+
144+
[RFC 195]: https://github.com/rust-lang/rfcs/blob/master/text/0195-associated-items.md
145+
146+
We've also [fixed a bug] with the `include!` macro in documentation tests: for relative
147+
paths, it erroneously was relative to the working directory, rather than to the current file.
148+
149+
[fixed a bug]: https://github.com/rust-lang/rust/pull/43782
150+
151+
See the [detailed release notes][notes] for more.
152+
153+
#### Library stabilizations
154+
155+
There's nothing *super* exciting in libraries this release, just a number of solid
156+
improvements and continued stabilizing of APIs.
157+
158+
The `unimplemented!` macro [now accepts
159+
messages](https://github.com/rust-lang/rust/pull/42155) that let you say why
160+
something is not yet implemented.
161+
162+
We [upgraded to Unicode 10.0.0](https://github.com/rust-lang/rust/pull/42999).
163+
164+
`min` and `max` on floating point types were [rewritten in
165+
Rust](https://github.com/rust-lang/rust/pull/42430), no longer relying on
166+
`cmath`.
167+
168+
We are shipping mitigations against [Stack
169+
Clash](https://access.redhat.com/security/vulnerabilities/stackguard) in this
170+
release, notably, [stack probes], and [skipping the main thread's manual
171+
stack guard on Linux]. You don't need to do anything to get these protections
172+
other than using Rust 1.20.
173+
174+
[stack probes]: https://github.com/rust-lang/rust/pull/42816
175+
[skipping the main thread's manual stack guard on Linux]: (https://github.com/rust-lang/rust/pull/43072)
176+
177+
We've added a new trio of sorting functions to the standard library:
178+
[`slice::sort_unstable_by_key`], [`slice::sort_unstable_by`], and
179+
[`slice::sort_unstable`]. You'll note that these all have "unstable" in the name.
180+
Stability is a property of sorting algorithms that may or may not matter to you,
181+
but now you have both options! Here's a brief summary: imagine we had a list
182+
of words like this:
183+
184+
```text
185+
rust
186+
crate
187+
package
188+
cargo
189+
```
190+
191+
Two of these words, `cargo` and `crate`, both start with the letter `c`. A stable
192+
sort that sorts only on the first letter must produce this result:
193+
194+
```text
195+
crate
196+
cargo
197+
rust
198+
package
199+
```
200+
201+
That is, becuase `crate` came before `cargo` in the original list, it must also be
202+
before it in the final list. An unstable sort could provide this result, but could
203+
also give this answer too:
204+
205+
```text
206+
cargo
207+
crate
208+
rust
209+
package
210+
```
211+
212+
That is, the results *may* not be in the same original order.
213+
214+
As you might imagine, less constraints often means faster results. If you don't care
215+
about stability, these sorts may be faster for you than the stable variants. As always,
216+
best to check both and see! These functions were added by [RFC 1884], if you'd like
217+
more details, including benchmarks.
218+
219+
[RFC 1884]: https://github.com/rust-lang/rfcs/blob/master/text/1884-unstable-sort.md
220+
221+
Additionally, the following APIs were also stabilized:
222+
223+
- [`CStr::into_c_string`]
224+
- [`CString::as_c_str`] and [`CString::into_boxed_c_str`]
225+
- [`Chain::get_mut`], [`Chain::get_ref`], and [`Chain::into_inner`]
226+
- [`Option::get_or_insert_with`] and [`Option::get_or_insert`]
227+
- [`OsStr::into_os_string`]
228+
- [`OsString::into_boxed_os_str`]
229+
- [`Take::get_mut`] and [`Take::get_ref`]
230+
- [`Utf8Error::error_len`]
231+
- [`char::EscapeDebug`] and [`char::escape_debug`]
232+
- [`compile_error!`]
233+
- [`f32::from_bits`] and [`f32::to_bits`]
234+
- [`f64::from_bits`] and [`f64::to_bits`]
235+
- [`mem::ManuallyDrop`]
236+
- [`str::from_boxed_utf8_unchecked`]
237+
- [`str::as_bytes_mut`]
238+
- [`str::from_utf8_mut`] and [`str::from_utf8_unchecked_mut`]
239+
- [`str::get_unchecked`] and [`str::get_unchecked_mut`]
240+
- [`str::get`] and [`str::get_mut`]
241+
- [`str::into_boxed_bytes`]
242+
243+
[`CStr::into_c_string`]: https://doc.rust-lang.org/std/ffi/struct.CStr.html#method.into_c_string
244+
[`CString::as_c_str`]: https://doc.rust-lang.org/std/ffi/struct.CString.html#method.as_c_str
245+
[`CString::into_boxed_c_str`]: https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str
246+
[`Chain::get_mut`]: https://doc.rust-lang.org/std/io/struct.Chain.html#method.get_mut
247+
[`Chain::get_ref`]: https://doc.rust-lang.org/std/io/struct.Chain.html#method.get_ref
248+
[`Chain::into_inner`]: https://doc.rust-lang.org/std/io/struct.Chain.html#method.into_inner
249+
[`Option::get_or_insert_with`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.get_or_insert_with
250+
[`Option::get_or_insert`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.get_or_insert
251+
[`OsStr::into_os_string`]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html#method.into_os_string
252+
[`OsString::into_boxed_os_str`]: https://doc.rust-lang.org/std/ffi/struct.OsString.html#method.into_boxed_os_str
253+
[`Take::get_mut`]: https://doc.rust-lang.org/std/io/struct.Take.html#method.get_mut
254+
[`Take::get_ref`]: https://doc.rust-lang.org/std/io/struct.Take.html#method.get_ref
255+
[`Utf8Error::error_len`]: https://doc.rust-lang.org/std/str/struct.Utf8Error.html#method.error_len
256+
[`char::EscapeDebug`]: https://doc.rust-lang.org/std/char/struct.EscapeDebug.html
257+
[`char::escape_debug`]: https://doc.rust-lang.org/std/primitive.char.html#method.escape_debug
258+
[`compile_error!`]: https://doc.rust-lang.org/std/macro.compile_error.html
259+
[`f32::from_bits`]: https://doc.rust-lang.org/std/primitive.f32.html#method.from_bits
260+
[`f32::to_bits`]: https://doc.rust-lang.org/std/primitive.f32.html#method.to_bits
261+
[`f64::from_bits`]: https://doc.rust-lang.org/std/primitive.f64.html#method.from_bits
262+
[`f64::to_bits`]: https://doc.rust-lang.org/std/primitive.f64.html#method.to_bits
263+
[`mem::ManuallyDrop`]: https://doc.rust-lang.org/std/mem/union.ManuallyDrop.html
264+
[`slice::sort_unstable_by_key`]: https://doc.rust-lang.org/std/primitive.slice.html#method.sort_unstable_by_key
265+
[`slice::sort_unstable_by`]: https://doc.rust-lang.org/std/primitive.slice.html#method.sort_unstable_by
266+
[`slice::sort_unstable`]: https://doc.rust-lang.org/std/primitive.slice.html#method.sort_unstable
267+
[`str::from_boxed_utf8_unchecked`]: https://doc.rust-lang.org/std/str/fn.from_boxed_utf8_unchecked.html
268+
[`str::as_bytes_mut`]: https://doc.rust-lang.org/std/primitive.str.html#method.as_bytes_mut
269+
[`str::from_utf8_mut`]: https://doc.rust-lang.org/std/str/fn.from_utf8_mut.html
270+
[`str::from_utf8_unchecked_mut`]: https://doc.rust-lang.org/std/str/fn.from_utf8_unchecked_mut.html
271+
[`str::get_mut`]: https://doc.rust-lang.org/std/primitive.str.html#method.get_mut
272+
[`str::get_unchecked_mut`]: https://doc.rust-lang.org/std/primitive.str.html#method.get_unchecked_mut
273+
[`str::get_unchecked`]: https://doc.rust-lang.org/std/primitive.str.html#method.get_unchecked
274+
[`str::get`]: https://doc.rust-lang.org/std/primitive.str.html#method.get
275+
[`str::into_boxed_bytes`]: https://doc.rust-lang.org/std/primitive.str.html#method.into_boxed_bytes
276+
277+
See the [detailed release notes][notes] for more.
278+
279+
#### Cargo features
280+
281+
Cargo has some nice upgrades this release. First of all, your crates.io
282+
authentication token used to be stored in `~/.cargo/config`. As a configuration
283+
file, this would often be stored with `644` permissions, that is, world-readable.
284+
But it has a secret token in it. We've [moved the token] to `~/.cargo/credentials`,
285+
so that it can be permissioned `600`, and hidden from other users on your system.
286+
287+
[moved the token]: https://github.com/rust-lang/cargo/pull/3978
288+
289+
If you used secondary binaries in a Cargo package, you know that they're kept
290+
in `src/bin`. However, sometimes, you want multiple secondary binaries that
291+
have significant logic; in that case, you'd have `src/bin/client.rs` and
292+
`src/bin/server.rs`, and any submodules for either of them would go in the
293+
same directory. This is confusing. Instead, [we now conventionally support]
294+
`src/bin/client/main.rs` and `src/bin/server/main.rs`, so that you can keep
295+
larger binaries more separate from one another.
296+
297+
[we now conventionally support]: https://github.com/rust-lang/cargo/pull/4214
298+
299+
See the [detailed release notes][notes] for more.
300+
301+
### Contributors to 1.20.0
302+
303+
Many people came together to create Rust 1.20. We couldn't have done it without
304+
all of you. [Thanks!](https://thanks.rust-lang.org/rust/1.20.0)

0 commit comments

Comments
 (0)