|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Announcing Rust 1.17" |
| 4 | +author: The Rust Core Team |
| 5 | +--- |
| 6 | + |
| 7 | +The Rust team is happy to announce the latest version of Rust, 1.17.0. 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.17 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.17.0][notes] on GitHub. |
| 19 | + |
| 20 | +[install]: https://www.rust-lang.org/install.html |
| 21 | +[notes]: https://github.com/rust-lang/rust/blob/rust-1.17-relnotes/RELEASES.md#version-1170-2017-04-27 |
| 22 | + |
| 23 | +### What's in 1.17.0 stable |
| 24 | + |
| 25 | +The story of Rust 1.17.0 is mostly one of small, quality of life improvements. For example, |
| 26 | +[the `'static` lifetime is now assumed in statics and consts](https://github.com/rust-lang/rust/pull/39265). When writing a const or static like this: |
| 27 | + |
| 28 | +```rust |
| 29 | +const NAME: &'static str = "Ferris"; |
| 30 | +static NAME: &'static str = "Ferris"; |
| 31 | +``` |
| 32 | + |
| 33 | +Rust 1.17 will allow you to elide the `'static`, since that's the only lifetime that makes |
| 34 | +sense: |
| 35 | + |
| 36 | +```rust |
| 37 | +const NAME: &str = "Ferris"; |
| 38 | +static NAME: &str = "Ferris"; |
| 39 | +``` |
| 40 | + |
| 41 | +In some situations, this can remove lots of boilerplate: |
| 42 | + |
| 43 | +```rust |
| 44 | +// old |
| 45 | +const NAMES: &'static [&'static str; 2] = &["Ferris", "Bors"]; |
| 46 | + |
| 47 | +// new |
| 48 | +const NAMES: &[&str; 2] = &["Ferris", "Bors"]; |
| 49 | +``` |
| 50 | + |
| 51 | +Another similar improvement is "field init shorthand." Similar to ECMAScript 6, |
| 52 | +which calls this "Object Literal Property Value Shorthand", duplication can be |
| 53 | +removed when declaring structs, like this: |
| 54 | + |
| 55 | +```rust |
| 56 | +// definitions |
| 57 | +struct Point { |
| 58 | + x: i32, |
| 59 | + y: i32, |
| 60 | +} |
| 61 | + |
| 62 | +let x = 5; |
| 63 | +let y = 6; |
| 64 | + |
| 65 | +// old |
| 66 | +let p = Point { |
| 67 | + x: x, |
| 68 | + y: y, |
| 69 | +}; |
| 70 | + |
| 71 | +// new |
| 72 | +let p = Point { |
| 73 | + x, |
| 74 | + y, |
| 75 | +}; |
| 76 | +``` |
| 77 | + |
| 78 | +That is, the `x, y` form will assume that its values are set to a variable |
| 79 | +with the same name in its scope. |
| 80 | + |
| 81 | +For another small quality of life improvement, it's common for new Rustaceans to |
| 82 | +try to use `+` to add two `&str`s together. This doesn't work, you can only add |
| 83 | +`String + &str`. As such, [a new error |
| 84 | +message](https://github.com/rust-lang/rust/pull/39116) was added to help users |
| 85 | +who make this mistake: |
| 86 | + |
| 87 | +```rust |
| 88 | +// code |
| 89 | +"foo" + "bar" |
| 90 | + |
| 91 | +// old |
| 92 | +error[E0369]: binary operation `+` cannot be applied to type `&'static str` |
| 93 | + --> <anon>:2:5 |
| 94 | + | |
| 95 | +2 | "foo" + "bar" |
| 96 | + | ^^^^^ |
| 97 | + | |
| 98 | +note: an implementation of `std::ops::Add` might be missing for `&'static str` |
| 99 | + --> <anon>:2:5 |
| 100 | + | |
| 101 | +2 | "foo" + "bar" |
| 102 | + | ^^^^^ |
| 103 | + |
| 104 | +// new |
| 105 | +error[E0369]: binary operation `+` cannot be applied to type `&'static str` |
| 106 | + --> <anon>:2:5 |
| 107 | + | |
| 108 | +2 | "foo" + "bar" |
| 109 | + | ^^^^^ |
| 110 | + | |
| 111 | + = note: `+` can't be used to concatenate two `&str` strings |
| 112 | +help: to_owned() can be used to create an owned `String` from a string |
| 113 | +reference. String concatenation appends the string on the right to the string on |
| 114 | +the left and may require reallocation. This requires ownership of the string on |
| 115 | +the left. |
| 116 | + | "foo".to_owned() + "bar" |
| 117 | +``` |
| 118 | + |
| 119 | +When using Cargo's build scripts, you must set the location of the script in your |
| 120 | +`Cargo.toml`. However, the vast majority of people wrote `build = "build.rs"`, using |
| 121 | +a `build.rs` file in the root of their project. [This convention is now encoded |
| 122 | +into Cargo](https://github.com/rust-lang/cargo/pull/3664), and will be assumed if |
| 123 | +`build.rs` exists. We've been warning about this change for the past few releases, |
| 124 | +and you can use `build = false` to opt out. |
| 125 | + |
| 126 | +This release marks [the removal](https://github.com/rust-lang/rust/pull/39431) |
| 127 | +of the old `Makefile` based build system. The new system, announced in Rust |
| 128 | +1.15, is written in Rust and primarily uses Cargo to drive the build. It is now |
| 129 | +mature enough to be the only build system. |
| 130 | + |
| 131 | +As part of that change, packages from crates.io can now be used within Rust's |
| 132 | +build system. The first one to be added was [mdBook](https://crates.io/crates/mdbook), |
| 133 | +and [it's now being used](https://github.com/rust-lang/rust/pull/39633) to render |
| 134 | +our various book-like documentation: |
| 135 | + |
| 136 | +* [The book](https://doc.rust-lang.org/stable/book/) ([repo](https://github.com/rust-lang/book)) |
| 137 | +* [The reference](https://doc.rust-lang.org/stable/reference/) ([repo](https://github.com/rust-lang-nursery/reference)) |
| 138 | +* [The nomicon](https://doc.rust-lang.org/stable/nomicon/) ([repo](https://github.com/rust-lang-nursery/nomicon)) |
| 139 | + |
| 140 | +In addition, see those links to their respective repositories; they've been |
| 141 | +moved out of tree. Also, we've added a fourth book, still in-tree: [The |
| 142 | +Unstable Book](https://doc.rust-lang.org/stable/unstable-book/). This |
| 143 | +provides an overview of unstable features by name, contains links to their |
| 144 | +tracking issues, and may contain initial documentation. |
| 145 | +If there's a feature you want to see stabilized, please get involved on |
| 146 | +its tracking issue! |
| 147 | + |
| 148 | +A few releases ago, `rustup` stopped installing documentation |
| 149 | +by default. We made this change to save some bandwidth and because not |
| 150 | +all users want a copy of the documentation locally. However, this created |
| 151 | +a pitfall: some users did not realize that this changed, and would only |
| 152 | +notice once they were no longer connected to the internet. In addition, |
| 153 | +some users *did* want to have a local copy of the docs, regardless of |
| 154 | +their connectivity. As such, we've [reverted the change](https://github.com/rust-lang/rust/pull/40526), and documentation is being |
| 155 | +installed by default again. |
| 156 | + |
| 157 | +Finally, while this release is full of improvements, there is one small |
| 158 | +step back we want to regretfully inform you about. On Windows, Visual |
| 159 | +Studio 2017 has been released, and Microsoft has changed the structure |
| 160 | +of how the software is installed. [Rust cannot automatically detect this |
| 161 | +location](https://github.com/rust-lang/rust/issues/38584), and while we |
| 162 | +were working on the neccesary changes, they did not make it in time for |
| 163 | +this release. Until then, Visual Studio 2015 still works fine, or you |
| 164 | +can run `vcvars.bat` on the command line. We hope to make this work |
| 165 | +in a seamless fashion soon. |
| 166 | + |
| 167 | +See the [detailed release notes][notes] for more. |
| 168 | + |
| 169 | +#### Library stabilizations |
| 170 | + |
| 171 | +19 new bits of API were stabilized this release: |
| 172 | + |
| 173 | +* [`Arc::into_raw`] and [`Rc::into_raw`] let you consume an `Arc` or `Rc` and get a raw pointer. |
| 174 | +* [`Arc::from_raw`] and [`Rc::from_raw`] let you take that raw pointer and get an `Arc` or `Rc`. |
| 175 | +* [`Arc::ptr_eq`] and [`Rc::ptr_eq`] return true if the two `Arc`s or two `Rc`s point to the same value (not just values that compare as equal). |
| 176 | +* [`Ordering::then`] lets you chain two `Ordering`s together, and [`Ordering::then_with`] lets you do it with a function. |
| 177 | +* [`BTreeMap::range`] allows you to iterate over a portion of a `BTreeMap`, and [`BTreeMap::range_mut`] lets you do it mutably. [`collections::Bound`] can give you even more control. |
| 178 | +* [`process::abort`] will completely terminate a process in an abnormal fashion. |
| 179 | +* [`ptr::read_unaligned`] and [`ptr::write_unaligned`] are like `ptr::read` and `ptr::write`, but without alignment requirements. |
| 180 | +* [`Result::expect_err`] mirrors `Result::expect`, but with the `Err` case rather than the `Ok` case. |
| 181 | +* [`Cell::swap`] is similar to `std::mem::swap`, but lets you do it with `&Cell` instead of `&mut T`. |
| 182 | +* [`Cell::replace`] is similar to `std::mem::replace`, but lets you do it with `&Cell` instead of `&mut T`. |
| 183 | +* [`Cell::into_inner`] lets you consume the `Cell`, and extract its value. |
| 184 | +* [`Cell::take`] lets you take the value out of a `Cell`, leaving its `Default::default` behind. |
| 185 | + |
| 186 | +[`Arc::from_raw`]: https://doc.rust-lang.org/std/sync/struct.Arc.html#method.from_raw |
| 187 | +[`Arc::into_raw`]: https://doc.rust-lang.org/std/sync/struct.Arc.html#method.into_raw |
| 188 | +[`Arc::ptr_eq`]: https://doc.rust-lang.org/std/sync/struct.Arc.html#method.ptr_eq |
| 189 | +[`BTreeMap::range_mut`]: https://doc.rust-lang.org/std/collections/btree_map/struct.BTreeMap.html#method.range_mut |
| 190 | +[`BTreeMap::range`]: https://doc.rust-lang.org/std/collections/btree_map/struct.BTreeMap.html#method.range |
| 191 | +[`Cell::into_inner`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.into_inner |
| 192 | +[`Cell::replace`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.replace |
| 193 | +[`Cell::swap`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.swap |
| 194 | +[`Cell::take`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.take |
| 195 | +[`Ordering::then_with`]: https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method.then_with |
| 196 | +[`Ordering::then`]: https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method.then |
| 197 | +[`Rc::from_raw`]: https://doc.rust-lang.org/std/rc/struct.Rc.html#method.from_raw |
| 198 | +[`Rc::into_raw`]: https://doc.rust-lang.org/std/rc/struct.Rc.html#method.into_raw |
| 199 | +[`Rc::ptr_eq`]: https://doc.rust-lang.org/std/rc/struct.Rc.html#method.ptr_eq |
| 200 | +[`Result::expect_err`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.expect_err |
| 201 | +[`collections::Bound`]: https://doc.rust-lang.org/std/collections/enum.Bound.html |
| 202 | +[`process::abort`]: https://doc.rust-lang.org/std/process/fn.abort.html |
| 203 | +[`ptr::read_unaligned`]: https://doc.rust-lang.org/std/ptr/fn.read_unaligned.html |
| 204 | +[`ptr::write_unaligned`]: https://doc.rust-lang.org/std/ptr/fn.write_unaligned.html |
| 205 | + |
| 206 | +In other changes, `Cell<T>` used to require that `T: Copy` for many of its methods, |
| 207 | +but [this has been relaxed significantly](https://github.com/rust-lang/rust/pull/39793). |
| 208 | + |
| 209 | +`Box<T>` [now implements](https://github.com/rust-lang/rust/pull/40009) over a dozen new |
| 210 | +conversions with `From`. |
| 211 | + |
| 212 | +`SocketAddr` and `IpAddr` have [some new conversions](https://github.com/rust-lang/rust/pull/39372) |
| 213 | +as well. Previously, you may have written code like this: |
| 214 | + |
| 215 | +```rust |
| 216 | +"127.0.0.1:3000".parse().unwrap() |
| 217 | +``` |
| 218 | + |
| 219 | +Now, you can write |
| 220 | + |
| 221 | +```rust |
| 222 | +SocketAddr::from(([127, 0, 0, 1], 3000)) |
| 223 | +// or even |
| 224 | +([127, 0, 0, 1], 3000).into()) |
| 225 | +``` |
| 226 | + |
| 227 | +This removes some unnecesary run-time parsing, and is roughly as readable, depending on |
| 228 | +your preferences. |
| 229 | + |
| 230 | +Backtraces [now have nicer formatting](https://github.com/rust-lang/rust/pull/38165), eliding |
| 231 | +some things by default. For example, the full backtrace: |
| 232 | + |
| 233 | +```text |
| 234 | +thread 'main' panicked at 'explicit panic', foo.rs:2 |
| 235 | +stack backtrace: |
| 236 | + 1: 0x55c39a23372c - std::sys::imp::backtrace::tracing::imp::write::hf33ae72d0baa11ed |
| 237 | + at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:42 |
| 238 | + 2: 0x55c39a23571e - std::panicking::default_hook::{{closure}}::h59672b733cc6a455 |
| 239 | + at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panicking.rs:351 |
| 240 | + 3: 0x55c39a235324 - std::panicking::default_hook::h1670459d2f3f8843 |
| 241 | + at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panicking.rs:367 |
| 242 | + 4: 0x55c39a235afb - std::panicking::rust_panic_with_hook::hcf0ddb069e7beee7 |
| 243 | + at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panicking.rs:555 |
| 244 | + 5: 0x55c39a22e866 - std::panicking::begin_panic::heb433e9aa28a7408 |
| 245 | + 6: 0x55c39a22e9bf - foo::main::hd216d4a160fcce19 |
| 246 | + 7: 0x55c39a23d44a - __rust_maybe_catch_panic |
| 247 | + at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libpanic_unwind/lib.rs:98 |
| 248 | + 8: 0x55c39a236006 - std::rt::lang_start::hd7c880a37a646e81 |
| 249 | + at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panicking.rs:436 |
| 250 | + at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panic.rs:361 |
| 251 | + at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/rt.rs:57 |
| 252 | + 9: 0x55c39a22e9e9 - main |
| 253 | + 10: 0x7f5e5ed3382f - __libc_start_main |
| 254 | + 11: 0x55c39a22e6b8 - _start |
| 255 | + 12: 0x0 - <unknown> |
| 256 | +``` |
| 257 | + |
| 258 | +is now instead |
| 259 | + |
| 260 | +```text |
| 261 | +thread 'main' panicked at 'explicit panic', foo.rs:2 |
| 262 | +stack backtrace: |
| 263 | + 0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace |
| 264 | + at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49 |
| 265 | + 1: std::sys_common::backtrace::_print |
| 266 | + at /checkout/src/libstd/sys_common/backtrace.rs:71 |
| 267 | + 2: std::panicking::default_hook::{{closure}} |
| 268 | + at /checkout/src/libstd/sys_common/backtrace.rs:60 |
| 269 | + at /checkout/src/libstd/panicking.rs:355 |
| 270 | + 3: std::panicking::default_hook |
| 271 | + at /checkout/src/libstd/panicking.rs:371 |
| 272 | + 4: std::panicking::rust_panic_with_hook |
| 273 | + at /checkout/src/libstd/panicking.rs:549 |
| 274 | + 5: std::panicking::begin_panic |
| 275 | + 6: foo::main |
| 276 | + 7: __rust_maybe_catch_panic |
| 277 | + at /checkout/src/libpanic_unwind/lib.rs:98 |
| 278 | + 8: std::rt::lang_start |
| 279 | + at /checkout/src/libstd/panicking.rs:433 |
| 280 | + at /checkout/src/libstd/panic.rs:361 |
| 281 | + at /checkout/src/libstd/rt.rs:57 |
| 282 | + 9: main |
| 283 | + 10: __libc_start_main |
| 284 | + 11: _start |
| 285 | +``` |
| 286 | + |
| 287 | +By default. You can set the environment variable `RUST_BACKTRACE=full` to get the full |
| 288 | +backtrace. We may be able to do more cleanup in the future; see [this bug](https://github.com/rust-lang/rust/pull/40264) for more. |
| 289 | + |
| 290 | +See the [detailed release notes][notes] for more. |
| 291 | + |
| 292 | +#### Cargo features |
| 293 | + |
| 294 | +Other than the previously mentioned `build.rs` changes, Cargo has a few new improvements. |
| 295 | +[`cargo check --all`](https://github.com/rust-lang/cargo/pull/3731) and |
| 296 | +[`cargo run --package`](https://github.com/rust-lang/cargo/pull/3691) are two missing |
| 297 | +flags that are now supported. |
| 298 | + |
| 299 | +You can now [opt in to ignoring SSL revocation checks](https://github.com/rust-lang/cargo/pull/3699). The default is still to check, of course. |
| 300 | + |
| 301 | +A new field in `Cargo.toml`, `required-features`, lets you [specify specific features |
| 302 | +that must be set for a target to be built](https://github.com/rust-lang/cargo/pull/3667). |
| 303 | +Here's an example: let's say that we are writing a crate that interacts with databases, |
| 304 | +and that we support multiple databases. We might have this in our `Cargo.toml`: |
| 305 | + |
| 306 | +```toml |
| 307 | +[features] |
| 308 | +# ... |
| 309 | +postgres = [] |
| 310 | +sqlite = [] |
| 311 | +tools = [] |
| 312 | +``` |
| 313 | + |
| 314 | +The `tools` feature allows us to include extra tooling, and the `postgres` and `sqlite` |
| 315 | +features control which databses we want to support. |
| 316 | + |
| 317 | +Previously, `cargo build` would attempt to build all targets, which is normally what |
| 318 | +you want. But what if we had a `src/bin/postgres-tool.rs`, that would only really |
| 319 | +be relevant if the `postgres` and `tools` features would be enabled? Previously, |
| 320 | +we would have to write something like this: |
| 321 | + |
| 322 | +```rust |
| 323 | +#[cfg(not(all(feature = "postgres", feature = "tools")))] |
| 324 | +fn main() { |
| 325 | + println!("This tool requires the `postgres` and `tools` features to be enabled."); |
| 326 | +} |
| 327 | + |
| 328 | +#[cfg(all(feature = "postgres", feature = "tools"))] |
| 329 | +fn main() { |
| 330 | + // real code |
| 331 | +} |
| 332 | +``` |
| 333 | + |
| 334 | +This is a lot of boilerplate to work around `cargo build`'s behavior. It's even |
| 335 | +more unfortunate with `examples/`, which are supposed to show off how to use |
| 336 | +your library, but this shenanigans is only relevant within the package, not if |
| 337 | +you were to try to use the example on your own. |
| 338 | + |
| 339 | +With the new `required-features` key, we can add this: |
| 340 | + |
| 341 | +```toml |
| 342 | +[[bin]] |
| 343 | +# ... |
| 344 | +required-features = ["postgres", "tools"] |
| 345 | +``` |
| 346 | + |
| 347 | +Now, `cargo build` will only build our `postgres-tool` if we have the two features |
| 348 | +set, and so we can write a normal `fn main` without all the `cfg` nonsense getting |
| 349 | +in the way. |
| 350 | + |
| 351 | +See the [detailed release notes][notes] for more. |
| 352 | + |
| 353 | +### Contributors to 1.17.0 |
| 354 | + |
| 355 | +Many people came together to create Rust 1.17. We couldn't have done it without |
| 356 | +all of you. [Thanks!](https://thanks.rust-lang.org/rust/1.17.0) |
0 commit comments