|
| 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