|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Announcing Rust 1.21" |
| 4 | +author: The Rust Core Team |
| 5 | +--- |
| 6 | + |
| 7 | +The Rust team is happy to announce the latest version of Rust, 1.21.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.21 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.21.0][notes] on GitHub. |
| 19 | + |
| 20 | +[install]: https://www.rust-lang.org/install.html |
| 21 | +[notes]: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1210-2017-10-12 |
| 22 | + |
| 23 | +### What's in 1.21.0 stable |
| 24 | + |
| 25 | +This release contains some very minor, but nice-to-have features, as well as |
| 26 | +some new documentation. |
| 27 | + |
| 28 | +First up, a small change to literals. Consider code like this: |
| 29 | + |
| 30 | +```rust |
| 31 | +let x = &5; |
| 32 | +``` |
| 33 | + |
| 34 | +In Rust, this code is synonymous with: |
| 35 | + |
| 36 | +```rust |
| 37 | +let _x = 5; |
| 38 | +let x = &_x; |
| 39 | +``` |
| 40 | + |
| 41 | +That is, the `5` here will be stored on the stack, or possibly in registers. |
| 42 | +`x` will be a reference to it. |
| 43 | + |
| 44 | +However, given that it's a literal integer, there's no reason that it *has* |
| 45 | +to be local like this. Imagine we had a function that took a `'static` argument, |
| 46 | +like `std::thread::spawn`. You might use `x` like this: |
| 47 | + |
| 48 | + |
| 49 | +```rust |
| 50 | +use std::thread; |
| 51 | + |
| 52 | +fn main() { |
| 53 | + let x = &5; |
| 54 | + |
| 55 | + thread::spawn(move || { |
| 56 | + println!("{}", x); |
| 57 | + }); |
| 58 | + |
| 59 | +} |
| 60 | +``` |
| 61 | + |
| 62 | +In previous versions of Rust, this would fail to compile: |
| 63 | + |
| 64 | +```text |
| 65 | +error[E0597]: borrowed value does not live long enough |
| 66 | + --> src/main.rs:4:14 |
| 67 | + | |
| 68 | +4 | let x = &5; |
| 69 | + | ^ does not live long enough |
| 70 | +... |
| 71 | +10 | } |
| 72 | + | - temporary value only lives until here |
| 73 | + | |
| 74 | + = note: borrowed value must be valid for the static lifetime... |
| 75 | +``` |
| 76 | + |
| 77 | +Because the `5` is local, so is its borrow, which doesn't satisfy the |
| 78 | +requirements for `spawn`. |
| 79 | + |
| 80 | +However, if you compile this on Rust 1.21, it will work. Why? Well, |
| 81 | +if the thing being referred to is okay to put into a `static`, we could |
| 82 | +instead de-sugar `let x = &5;` like this: |
| 83 | + |
| 84 | +```rust |
| 85 | +static FIVE: i32 = 5; |
| 86 | + |
| 87 | +let x = &FIVE; |
| 88 | +``` |
| 89 | + |
| 90 | +Here, since the `FIVE` is `static`, `x` is a `&'static i32`. And so this |
| 91 | +is what Rust will now do in this kind of case. For full details, see [RFC 1414], |
| 92 | +which was accepted in January, but started in December of 2015! |
| 93 | + |
| 94 | +[RFC 1414]: https://github.com/rust-lang/rfcs/blob/master/text/1414-rvalue_static_promotion.md |
| 95 | + |
| 96 | +We [now run LLVM in parallel while generating |
| 97 | +code](https://github.com/rust-lang/rust/pull/43506), which should reduce peak |
| 98 | +memory usage. |
| 99 | + |
| 100 | +The [RLS](https://github.com/rust-lang-nursery/rls/) can now be installed |
| 101 | +[through rustup](https://github.com/rust-lang/rust/pull/44204) by invoking |
| 102 | +`rustup component add rls-preview`. In general, many useful Rust developer |
| 103 | +tools such as the RLS, Clippy, and `rustfmt` need nightly Rust; this is the |
| 104 | +first steps toward having them work on stable Rust. Please check out the |
| 105 | +preview, and you'll hear more about these plans in the future. |
| 106 | + |
| 107 | +Finally, a few documentation improvements. First up, if you visit [the docs |
| 108 | +for `std::os`](https://doc.rust-lang.org/stable/std/os/), which contains |
| 109 | +operating-system specific functionality, you'll now see more than just `linux`, |
| 110 | +the platform we build the documentation on. We've long regretted that the hosted |
| 111 | +version of the documentation has been Linux-specific; this is a first step towards |
| 112 | +rectifying that. This is [specific to the standard |
| 113 | +library](https://github.com/rust-lang/rust/pull/43348) and not for general use; |
| 114 | +we hope to improve this further in the future. |
| 115 | + |
| 116 | +Next, [Cargo's docs are moving!](https://github.com/rust-lang/rust/pull/43916) |
| 117 | +Historically, Cargo's docs were hosted on doc.crates.io, which doesn't follow |
| 118 | +the release train model, even though Cargo itself does. This led to situations |
| 119 | +where a feature would land in Cargo nightly, the docs would be updated, and |
| 120 | +then for up to twelve weeks, users would *think* that it should work, but it |
| 121 | +wouldn't yet. [https://doc.rust-lang.org/cargo](https://doc.rust-lang.org/cargo) |
| 122 | +will be the new home of Cargo's docs, though for now, that URL is a redirect to |
| 123 | +doc.crates.io. Future releases will move Cargo's docs over, and at that point, |
| 124 | +doc.crates.io will redirect to doc.rust-lang.org/cargo. Cargo's docs have long |
| 125 | +needed a refreshing, so expect to hear more news about Cargo's docs generally |
| 126 | +in the future! |
| 127 | + |
| 128 | +Finally, until now, `rustdoc` did not have any documentation. This is now |
| 129 | +[fixed](https://github.com/rust-lang/rust/pull/43863), with a new "`rustdoc` |
| 130 | +Book," located at |
| 131 | +[https://doc.rust-lang.org/rustdoc](https://doc.rust-lang.org/rustdoc). These |
| 132 | +docs are fairly bare-bones at the moment, but we'll be improving them over |
| 133 | +time. |
| 134 | + |
| 135 | +See the [detailed release notes][notes] for more. |
| 136 | + |
| 137 | +#### Library stabilizations |
| 138 | + |
| 139 | +Not too many stabilizations this release, but there's one really great |
| 140 | +quality of life change: due to the lack of type-level integers, arrays only |
| 141 | +supported various traits up to size 32. This [has now been fixed for the |
| 142 | +`Clone` trait](https://github.com/rust-lang/rust/pull/43690), which also |
| 143 | +caused a lot of ICEs at times, when a type would be `Copy` but not `Clone`. |
| 144 | +For other traits, [an RFC for type-level integers was accepted |
| 145 | +recently](https://github.com/rust-lang/rfcs/blob/master/text/2000-const-generics.md), |
| 146 | +which may help with this situation. That change has yet to be implemented, however, |
| 147 | +though pre-requisite work is ongoing at the moment. |
| 148 | + |
| 149 | +Next, [`Iterator::for_each`](https://github.com/rust-lang/rust/pull/44567) has |
| 150 | +been stabilized, letting you consume an iterator for side effects without needing |
| 151 | +a `for` loop: |
| 152 | + |
| 153 | +```rust |
| 154 | +// old |
| 155 | +for i in 0..10 { |
| 156 | + println!("{}", i); |
| 157 | +} |
| 158 | + |
| 159 | +// new |
| 160 | +(0..10).for_each(|i| println!("{}", i)); |
| 161 | +``` |
| 162 | + |
| 163 | +The correct one to use depends on your situation; in the sample above, the `for` loop |
| 164 | +is pretty striaghtforward. But when you're chaining a number of iterators together, |
| 165 | +the `for_each` version is sometimes clearer. Consider this: |
| 166 | + |
| 167 | +```rust |
| 168 | +// old |
| 169 | +for i in (0..100).map(|x| x + 1).filter(|x| x % 2 == 0) { |
| 170 | + println!("{}", i); |
| 171 | +} |
| 172 | + |
| 173 | +// new |
| 174 | +(0..100) |
| 175 | + .map(|x| x + 1) |
| 176 | + .filter(|x| x % 2 == 0) |
| 177 | + .for_each(|i| println!("{}", i)); |
| 178 | +``` |
| 179 | + |
| 180 | +[`Rc<T>` and `Arc<T>` now implement `From<&[T]> where T: Clone`, `From<str>`, |
| 181 | +`From<String>`, `From<Box<T>> where T: ?Sized`, and |
| 182 | +`From<Vec<T>>`.](https://github.com/rust-lang/rust/pull/42565) |
| 183 | + |
| 184 | +The [`max` and `min` functions on the `Ord` |
| 185 | +trait](https://github.com/rust-lang/rust/pull/44593) are now stable. |
| 186 | + |
| 187 | +The [`needs_drop` intrinsic](https://github.com/rust-lang/rust/pull/44639) |
| 188 | +is now stable. |
| 189 | + |
| 190 | +Finally, [`std::mem::discriminant` has been |
| 191 | +stabilized](https://doc.rust-lang.org/std/mem/fn.discriminant.html), allowing |
| 192 | +you to see what variant an `enum` instance is without a `match` statement. |
| 193 | + |
| 194 | +See the [detailed release notes][notes] for more. |
| 195 | + |
| 196 | +#### Cargo features |
| 197 | + |
| 198 | +Beyond the documentation features listed above, Cargo is gaining one major |
| 199 | +feature in this release: |
| 200 | +[`[patch]`](https://github.com/rust-lang/cargo/pull/4123). Designed in [RFC |
| 201 | +1969](https://github.com/rust-lang/rfcs/blob/master/text/1969-cargo-prepublish.md), |
| 202 | +the `[patch]` section of your `Cargo.toml` can be used when you want to |
| 203 | +override certain parts of your dependency graph. We also have a feature, |
| 204 | +`[replace]` that has similar functionality. In many ways, `[patch]` is the new |
| 205 | +`[replace]`, and while we have no plans to deprecate or remove `[replace]`, |
| 206 | +at this point, you should use `[patch]` instead of `[replace]`. |
| 207 | + |
| 208 | +So what's it look like? Let's say we have a `Cargo.toml` that looks like this: |
| 209 | + |
| 210 | +```toml |
| 211 | +[dependencies] |
| 212 | +foo = "1.2.3" |
| 213 | +``` |
| 214 | + |
| 215 | +In addition, our `foo` crate depends on a `bar` crate, and we find a bug in |
| 216 | +`bar`. To test this out, we'd download the source code for `bar`, and then |
| 217 | +update our `Cargo.toml`: |
| 218 | + |
| 219 | +```toml |
| 220 | +[dependencies] |
| 221 | +foo = "1.2.3" |
| 222 | + |
| 223 | +[patch.crates-io] |
| 224 | +bar = { path = '/path/to/bar' } |
| 225 | +``` |
| 226 | + |
| 227 | +Now, when you `cargo build`, it will use the local version of `bar`, rather |
| 228 | +than the one from `crates.io` that `foo` depends on. |
| 229 | + |
| 230 | +For more details, see the |
| 231 | +[documentation](http://doc.crates.io/manifest.html#the-patch-section). |
| 232 | + |
| 233 | +Additionally: |
| 234 | + |
| 235 | +* [you can now `cargo install` multiple crates at |
| 236 | + once](https://github.com/rust-lang/cargo/pull/4216) |
| 237 | +* [If you're in a virtual workspace, `--all` is now |
| 238 | + applied automatically](https://github.com/rust-lang/cargo/pull/4335). |
| 239 | +* [`include` and `exclude` fields in your `Cargo.toml` accepts patterns similar |
| 240 | + to a `.gitignore`](https://github.com/rust-lang/cargo/pull/4270). |
| 241 | + |
| 242 | +See the [detailed release notes][notes] for more. |
| 243 | + |
| 244 | +### Contributors to 1.21.0 |
| 245 | + |
| 246 | +Many people came together to create Rust 1.21. We couldn't have done it without |
| 247 | +all of you. [Thanks!](https://thanks.rust-lang.org/rust/1.21.0) |
0 commit comments