Skip to content

Release post for Rust 1.17 #162

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 27, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
356 changes: 356 additions & 0 deletions _posts/2017-04-27-Rust-1.17.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,356 @@
---
layout: post
title: "Announcing Rust 1.17"
author: The Rust Core Team
---

The Rust team is happy to announce the latest version of Rust, 1.17.0. Rust is a
systems programming language focused on safety, speed, and concurrency.

If you have a previous version of Rust installed, getting Rust 1.17 is as easy as:

```bash
$ rustup update stable
```

If you don't have it already, you can [get `rustup`][install] from the
appropriate page on our website, and check out the [detailed release notes for
1.17.0][notes] on GitHub.

[install]: https://www.rust-lang.org/install.html
[notes]: https://github.com/rust-lang/rust/blob/rust-1.17-relnotes/RELEASES.md#version-1170-2017-04-27

### What's in 1.17.0 stable

The story of Rust 1.17.0 is mostly one of small, quality of life improvements. For example,
[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:

```rust
const NAME: &'static str = "Ferris";
static NAME: &'static str = "Ferris";
```

Rust 1.17 will allow you to elide the `'static`, since that's the only lifetime that makes
sense:

```rust
const NAME: &str = "Ferris";
static NAME: &str = "Ferris";
```

In some situations, this can remove lots of boilerplate:

```rust
// old
const NAMES: &'static [&'static str; 2] = &["Ferris", "Bors"];

// new
const NAMES: &[&str; 2] = &["Ferris", "Bors"];
```

Another similar improvement is "field init shorthand." Similar to ECMAScript 6,
which calls this "Object Literal Property Value Shorthand", duplication can be
removed when declaring structs, like this:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a link to more information or documentation about this feature? It should appear somewhere right? The Reference? Something like that? I don't know where to look, but I'm guessing it has to be there somewhere.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's in the reference, there's a PR open for RBE (to be merged after the release thanks to RBE's deploy process), and the book should mention it.

There's not more to it than what's described here, though.


```rust
// definitions
struct Point {
x: i32,
y: i32,
}

let x = 5;
let y = 6;

// old
let p = Point {
x: x,
y: y,
};

// new
let p = Point {
x,
y,
};
```

That is, the `x, y` form will assume that its values are set to a variable
with the same name in its scope.

For another small quality of life improvement, it's common for new Rustaceans to
try to use `+` to add two `&str`s together. This doesn't work, you can only add
`String + &str`. As such, [a new error
message](https://github.com/rust-lang/rust/pull/39116) was added to help users
who make this mistake:

```rust
// code
"foo" + "bar"

// old
error[E0369]: binary operation `+` cannot be applied to type `&'static str`
--> <anon>:2:5
|
2 | "foo" + "bar"
| ^^^^^
|
note: an implementation of `std::ops::Add` might be missing for `&'static str`
--> <anon>:2:5
|
2 | "foo" + "bar"
| ^^^^^

// new
error[E0369]: binary operation `+` cannot be applied to type `&'static str`
--> <anon>:2:5
|
2 | "foo" + "bar"
| ^^^^^
|
= note: `+` can't be used to concatenate two `&str` strings
help: to_owned() can be used to create an owned `String` from a string
reference. String concatenation appends the string on the right to the string on
the left and may require reallocation. This requires ownership of the string on
the left.
| "foo".to_owned() + "bar"
```

When using Cargo's build scripts, you must set the location of the script in your
`Cargo.toml`. However, the vast majority of people wrote `build = "build.rs"`, using
a `build.rs` file in the root of their project. [This convention is now encoded
into Cargo](https://github.com/rust-lang/cargo/pull/3664), and will be assumed if
`build.rs` exists. We've been warning about this change for the past few releases,
and you can use `build = false` to opt out.

This release marks [the removal](https://github.com/rust-lang/rust/pull/39431)
of the old `Makefile` based build system. The new system, announced in Rust
1.15, is written in Rust and primarily uses Cargo to drive the build. It is now
mature enough to be the only build system.

As part of that change, packages from crates.io can now be used within Rust's
build system. The first one to be added was [mdBook](https://crates.io/crates/mdbook),
and [it's now being used](https://github.com/rust-lang/rust/pull/39633) to render
our various book-like documentation:

* [The book](https://doc.rust-lang.org/stable/book/) ([repo](https://github.com/rust-lang/book))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't generally applicable to all /stable/ links, but it could be appropriate to link these to /1.17.0/ rather than /stable/, since the point of the links was to showcase some kind of specific difference in rendering. If the rendering changes again in the future, the link to /stable/ would probably land the user on something that wasn't actually generated with mdBook.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general we always default to /stable, I agree that maybe changing this convention in the future is a good idea though

* [The reference](https://doc.rust-lang.org/stable/reference/) ([repo](https://github.com/rust-lang-nursery/reference))
* [The nomicon](https://doc.rust-lang.org/stable/nomicon/) ([repo](https://github.com/rust-lang-nursery/nomicon))

In addition, see those links to their respective repositories; they've been
moved out of tree. Also, we've added a fourth book, still in-tree: [The
Unstable Book](https://doc.rust-lang.org/stable/unstable-book/). This
provides an overview of unstable features by name, contains links to their
tracking issues, and may contain initial documentation.
If there's a feature you want to see stabilized, please get involved on
its tracking issue!

A few releases ago, `rustup` stopped installing documentation
by default. We made this change to save some bandwidth and because not
all users want a copy of the documentation locally. However, this created
a pitfall: some users did not realize that this changed, and would only
notice once they were no longer connected to the internet. In addition,
some users *did* want to have a local copy of the docs, regardless of
their connectivity. As such, we've [reverted the change](https://github.com/rust-lang/rust/pull/40526), and documentation is being
installed by default again.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, can you also link me to something explaining exactly what this means, how I'd use it, where to find it, etc.?

Also, that long line could take a break.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea where this is, if @brson has ideas for a link, please add them in!


Finally, while this release is full of improvements, there is one small
step back we want to regretfully inform you about. On Windows, Visual
Studio 2017 has been released, and Microsoft has changed the structure
of how the software is installed. [Rust cannot automatically detect this
location](https://github.com/rust-lang/rust/issues/38584), and while we
were working on the neccesary changes, they did not make it in time for
this release. Until then, Visual Studio 2015 still works fine, or you
can run `vcvars.bat` on the command line. We hope to make this work
in a seamless fashion soon.

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

#### Library stabilizations

19 new bits of API were stabilized this release:

* [`Arc::into_raw`] and [`Rc::into_raw`] let you consume an `Arc` or `Rc` and get a raw pointer.
* [`Arc::from_raw`] and [`Rc::from_raw`] let you take that raw pointer and get an `Arc` or `Rc`.
* [`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).
* [`Ordering::then`] lets you chain two `Ordering`s together, and [`Ordering::then_with`] lets you do it with a function.
* [`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.
* [`process::abort`] will completely terminate a process in an abnormal fashion.
* [`ptr::read_unaligned`] and [`ptr::write_unaligned`] are like `ptr::read` and `ptr::write`, but without alignment requirements.
* [`Result::expect_err`] mirrors `Result::expect`, but with the `Err` case rather than the `Ok` case.
* [`Cell::swap`] is similar to `std::mem::swap`, but lets you do it with `&Cell` instead of `&mut T`.
* [`Cell::replace`] is similar to `std::mem::replace`, but lets you do it with `&Cell` instead of `&mut T`.
* [`Cell::into_inner`] lets you consume the `Cell`, and extract its value.
* [`Cell::take`] lets you take the value out of a `Cell`, leaving its `Default::default` behind.

[`Arc::from_raw`]: https://doc.rust-lang.org/std/sync/struct.Arc.html#method.from_raw
[`Arc::into_raw`]: https://doc.rust-lang.org/std/sync/struct.Arc.html#method.into_raw
[`Arc::ptr_eq`]: https://doc.rust-lang.org/std/sync/struct.Arc.html#method.ptr_eq
[`BTreeMap::range_mut`]: https://doc.rust-lang.org/std/collections/btree_map/struct.BTreeMap.html#method.range_mut
[`BTreeMap::range`]: https://doc.rust-lang.org/std/collections/btree_map/struct.BTreeMap.html#method.range
[`Cell::into_inner`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.into_inner
[`Cell::replace`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.replace
[`Cell::swap`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.swap
[`Cell::take`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.take
[`Ordering::then_with`]: https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method.then_with
[`Ordering::then`]: https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method.then
[`Rc::from_raw`]: https://doc.rust-lang.org/std/rc/struct.Rc.html#method.from_raw
[`Rc::into_raw`]: https://doc.rust-lang.org/std/rc/struct.Rc.html#method.into_raw
[`Rc::ptr_eq`]: https://doc.rust-lang.org/std/rc/struct.Rc.html#method.ptr_eq
[`Result::expect_err`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.expect_err
[`collections::Bound`]: https://doc.rust-lang.org/std/collections/enum.Bound.html
[`process::abort`]: https://doc.rust-lang.org/std/process/fn.abort.html
[`ptr::read_unaligned`]: https://doc.rust-lang.org/std/ptr/fn.read_unaligned.html
[`ptr::write_unaligned`]: https://doc.rust-lang.org/std/ptr/fn.write_unaligned.html

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should all these be to /stable/ like the earlier links were? Is that the most forward-appropriate link to be using?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these URLs are an alias to /stable; now that they're stable, they should always be there.


In other changes, `Cell<T>` used to require that `T: Copy` for many of its methods,
but [this has been relaxed significantly](https://github.com/rust-lang/rust/pull/39793).

`Box<T>` [now implements](https://github.com/rust-lang/rust/pull/40009) over a dozen new
conversions with `From`.

`SocketAddr` and `IpAddr` have [some new conversions](https://github.com/rust-lang/rust/pull/39372)
as well. Previously, you may have written code like this:

```rust
"127.0.0.1:3000".parse().unwrap()
```

Now, you can write

```rust
SocketAddr::from(([127, 0, 0, 1], 3000))
// or even
([127, 0, 0, 1], 3000).into())
```

This removes some unnecesary run-time parsing, and is roughly as readable, depending on
your preferences.

Backtraces [now have nicer formatting](https://github.com/rust-lang/rust/pull/38165), eliding
some things by default. For example, the full backtrace:

```text
thread 'main' panicked at 'explicit panic', foo.rs:2
stack backtrace:
1: 0x55c39a23372c - std::sys::imp::backtrace::tracing::imp::write::hf33ae72d0baa11ed
at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:42
2: 0x55c39a23571e - std::panicking::default_hook::{{closure}}::h59672b733cc6a455
at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panicking.rs:351
3: 0x55c39a235324 - std::panicking::default_hook::h1670459d2f3f8843
at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panicking.rs:367
4: 0x55c39a235afb - std::panicking::rust_panic_with_hook::hcf0ddb069e7beee7
at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panicking.rs:555
5: 0x55c39a22e866 - std::panicking::begin_panic::heb433e9aa28a7408
6: 0x55c39a22e9bf - foo::main::hd216d4a160fcce19
7: 0x55c39a23d44a - __rust_maybe_catch_panic
at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libpanic_unwind/lib.rs:98
8: 0x55c39a236006 - std::rt::lang_start::hd7c880a37a646e81
at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panicking.rs:436
at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panic.rs:361
at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/rt.rs:57
9: 0x55c39a22e9e9 - main
10: 0x7f5e5ed3382f - __libc_start_main
11: 0x55c39a22e6b8 - _start
12: 0x0 - <unknown>
```

is now instead

```text
thread 'main' panicked at 'explicit panic', foo.rs:2
stack backtrace:
0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::_print
at /checkout/src/libstd/sys_common/backtrace.rs:71
2: std::panicking::default_hook::{{closure}}
at /checkout/src/libstd/sys_common/backtrace.rs:60
at /checkout/src/libstd/panicking.rs:355
3: std::panicking::default_hook
at /checkout/src/libstd/panicking.rs:371
4: std::panicking::rust_panic_with_hook
at /checkout/src/libstd/panicking.rs:549
5: std::panicking::begin_panic
6: foo::main
7: __rust_maybe_catch_panic
at /checkout/src/libpanic_unwind/lib.rs:98
8: std::rt::lang_start
at /checkout/src/libstd/panicking.rs:433
at /checkout/src/libstd/panic.rs:361
at /checkout/src/libstd/rt.rs:57
9: main
10: __libc_start_main
11: _start
```

By default. You can set the environment variable `RUST_BACKTRACE=full` to get the full
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.

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

#### Cargo features

Other than the previously mentioned `build.rs` changes, Cargo has a few new improvements.
[`cargo check --all`](https://github.com/rust-lang/cargo/pull/3731) and
[`cargo run --package`](https://github.com/rust-lang/cargo/pull/3691) are two missing
flags that are now supported.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do they do, can you link me to the documentation for these new flags?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's no specific new docs, as these do what cargo check and cargo run do as normal, but were just missing these standard flags


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.

A new field in `Cargo.toml`, `required-features`, lets you [specify specific features
that must be set for a target to be built](https://github.com/rust-lang/cargo/pull/3667).
Here's an example: let's say that we are writing a crate that interacts with databases,
and that we support multiple databases. We might have this in our `Cargo.toml`:

```toml
[features]
# ...
postgres = []
sqlite = []
tools = []
```

The `tools` feature allows us to include extra tooling, and the `postgres` and `sqlite`
features control which databses we want to support.

Previously, `cargo build` would attempt to build all targets, which is normally what
you want. But what if we had a `src/bin/postgres-tool.rs`, that would only really
be relevant if the `postgres` and `tools` features would be enabled? Previously,
we would have to write something like this:

```rust
#[cfg(not(all(feature = "postgres", feature = "tools")))]
fn main() {
println!("This tool requires the `postgres` and `tools` features to be enabled.");
}

#[cfg(all(feature = "postgres", feature = "tools"))]
fn main() {
// real code
}
```

This is a lot of boilerplate to work around `cargo build`'s behavior. It's even
more unfortunate with `examples/`, which are supposed to show off how to use
your library, but this shenanigans is only relevant within the package, not if
you were to try to use the example on your own.

With the new `required-features` key, we can add this:

```toml
[[bin]]
# ...
required-features = ["postgres", "tools"]
```

Now, `cargo build` will only build our `postgres-tool` if we have the two features
set, and so we can write a normal `fn main` without all the `cfg` nonsense getting
in the way.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you fill in at least enough of the part currently marked # ... after [[bin]] to show how one of these targets works. The examples on the crates.io docs (wouldn't hurt to link) don't actually show any usage of multiple [[bin]] sections, so I couldn't figure out what this meant until I eventually broke down and did a Google search.

Actually, it seems kind of backwards that this release notes example is more thorough than the one on the crates.io site. Maybe someone can ping whoever is in charge of those?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you fill in at least enough of the part currently marked # ... after [[bin]] to show how one of these targets works.

That would depend on the details of the project itself, which isn't the important part here.

Maybe someone can ping whoever is in charge of those?

Guess who that is? :) Anyone could port this back to Cargo's docs, and in general, I have a "rehaul Cargo's docs) on my plate in the future.


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

### Contributors to 1.17.0

Many people came together to create Rust 1.17. We couldn't have done it without
all of you. [Thanks!](https://thanks.rust-lang.org/rust/1.17.0)