|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Announcing Rust 1.18" |
| 4 | +author: The Rust Core Team |
| 5 | +--- |
| 6 | + |
| 7 | +The Rust team is happy to announce the latest version of Rust, 1.18.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.18 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.18.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-1180-2017-06-08 |
| 22 | + |
| 23 | +### What's in 1.18.0 stable |
| 24 | + |
| 25 | +Rust 1.18.0 is similar to many of our releases: no big bombshells, just a number |
| 26 | +of improvements, cleanups, and new features. |
| 27 | + |
| 28 | +One of the largest changes is a long time coming: core team members Carol |
| 29 | +Nichols and Steve Klabnik have been writing a new edition of "The Rust |
| 30 | +Programming Language", the official book about Rust. It's being [written openly |
| 31 | +on GitHub](https://github.com/rust-lang/book), and has over a hundred |
| 32 | +contributors in total. This release [includes the first draft of the second |
| 33 | +edition in our online documentation](https://doc.rust-lang.org/stable/book/). |
| 34 | +19 out of 20 chapters have a draft; the draft of chapter 20 will land in the |
| 35 | +Rust 1.19. When the book is done, a print version will be made available through |
| 36 | +[No Starch Press](https://www.nostarch.com/Rust), if you'd like a paper copy. |
| 37 | +While first drafts of the chapters are available, we're still working with the |
| 38 | +editors at No Starch to improve the text, so there's more to do, but we wanted |
| 39 | +to start getting a wider audience now. The new edition is a complete re-write |
| 40 | +from the ground up, using the last two years of knowledge we've gained from |
| 41 | +teaching people Rust. You'll find brand-new explanations for a lot of Rust's |
| 42 | +core concepts, new projects to build, and all kinds of other good stuff. Please |
| 43 | +check it out and let us know what you think! |
| 44 | + |
| 45 | +As for the language itself, an old feature has learned some new tricks: the |
| 46 | +`pub` keyword has been expanded a bit. Experienced Rustaceans will know that |
| 47 | +items are private by default in Rust, and you can use the `pub` keyword to make |
| 48 | +them public. In Rust 1.18.0, `pub` has [gained a new |
| 49 | +form](https://github.com/rust-lang/rust/pull/40556): |
| 50 | + |
| 51 | +```rust |
| 52 | +pub(crate) bar; |
| 53 | +``` |
| 54 | + |
| 55 | +The bit inside of `()` is a 'restriction', which refines the notion of how this |
| 56 | +is made public. Using the `crate` keyword like the example above means that |
| 57 | +`bar` would be public to the entire crate, but not outside of it. This makes it |
| 58 | +easier to declare APIs that are "public to your crate", but not exposed to your |
| 59 | +users. This was *possible* with the current module system, but often very awkward. |
| 60 | + |
| 61 | +You can also specify a path, like this: |
| 62 | + |
| 63 | +```rust |
| 64 | +pub(a::b::c) foo; |
| 65 | +``` |
| 66 | + |
| 67 | +This means "usable within the hierarchy of `a::b::c`, but not elsewhere." This |
| 68 | +feature was defined in [RFC |
| 69 | +1422](https://github.com/rust-lang/rfcs/blob/master/text/1422-pub-restricted.md) |
| 70 | + |
| 71 | +For our Windows users, Rust 1.18.0 has [a new attribute, |
| 72 | +`#![windows_subsystem]`](https://github.com/rust-lang/rust/pull/40870). It |
| 73 | +works like this: |
| 74 | + |
| 75 | +```rust |
| 76 | +#![windows_subsystem(console)] |
| 77 | +#![windows_subsystem(windows)] |
| 78 | +``` |
| 79 | + |
| 80 | +These control the [`/SUBSYSTEM` flag](https://msdn.microsoft.com/en-us/library/fcc1zstk.aspx) |
| 81 | +in the linker. For now, only `console` and `windows` are supported. |
| 82 | + |
| 83 | +When is this useful? In the simplest terms, if you're developing a graphical |
| 84 | +application, and do not specify `windows`, a console window would flash up upon |
| 85 | +your application's start. With this flag, it won't. |
| 86 | + |
| 87 | +Finally, Rust's tuples, enum variant fields, and structs (without `#[repr]`) have |
| 88 | +always had an undefined layout. [We've turned on automatic re-ordering](https://github.com/rust-lang/rust/pull/40377), which can result in smaller sizes |
| 89 | +through reducing padding. Consider a struct like this: |
| 90 | + |
| 91 | +```rust |
| 92 | +struct Suboptimal(u8, u16, u8); |
| 93 | +``` |
| 94 | + |
| 95 | +In previous versions of Rust on the x86_64 platform, this struct would have the |
| 96 | +size of six bytes. But looking at the source, you'd expect it to have four. The |
| 97 | +extra two bytes come from padding; given that we have a `u16` here, it should be |
| 98 | +aligned to two bytes. But in this case, it's at offset one. To move it to offset |
| 99 | +two, another byte of padding is placed after the first `u8`. To give the whole struct |
| 100 | +a proper alignment, another byte is added after the second `u8` as well, giving us |
| 101 | +`1 + 1 (padding) + 2 + 1 + 1 (padding) = 6 bytes`. |
| 102 | + |
| 103 | +But what if our struct looked like this? |
| 104 | + |
| 105 | +```rust |
| 106 | +struct Optimal(u8, u8, u16); |
| 107 | +``` |
| 108 | + |
| 109 | +This struct is properly aligned; the `u16` lies on a two byte boundary, and so does |
| 110 | +the entire struct. No padding is needed. This gives us `1 + 1 + 2 = 4 bytes`. |
| 111 | + |
| 112 | +When designing Rust, stuff like this is why we left the details here undefined. |
| 113 | +It allows for exactly this kind of thing: the compiler can optimize `Suboptimal` |
| 114 | +into `Optimal` automatically. And if you check the sizes of `Suboptimal` and |
| 115 | +`Optimal` on Rust 1.18.0, you'll see that they both have a size of four bytes. |
| 116 | + |
| 117 | +We've been planning this for a while; previous versions of Rust included this |
| 118 | +optimization on the nightly channel, but some people wrote unsafe code that |
| 119 | +assumed the exact details of the representation. We rolled it back while we fixed |
| 120 | +all instances of this that we know about, but if you find some code breaks due to |
| 121 | +this, you should fix it! In the meantime, there's also a flag you can use to control |
| 122 | +this. Imagine we have `Suboptimal` in a file named `foo.rs`, along with a `main` |
| 123 | +function that prints out its size: |
| 124 | + |
| 125 | +```rust |
| 126 | +> rustc foo.rs |
| 127 | +> ./foo |
| 128 | +4 |
| 129 | +> rustc foo.rs -Z fuel=foo=0 |
| 130 | +optimization-fuel-exhausted: Reorder fields of "Suboptimal" |
| 131 | +> ./foo |
| 132 | +6 |
| 133 | +``` |
| 134 | + |
| 135 | +This flag is based on an idea called "[Optimization |
| 136 | +fuel](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/07/dfopt-popl10.pdf)": |
| 137 | + |
| 138 | +> It works by giving the optimizer a finite supply of optimization fuel. Each |
| 139 | +> time a rewrite function proposes to replace a node, one unit of fuel is |
| 140 | +> consumed. When the optimizer runs out of fuel, further rewrites are |
| 141 | +> suppressed. |
| 142 | +
|
| 143 | +Currently, this is the only optimization that uses the "fuel" concept. By |
| 144 | +setting the fuel to zero, `rustc` will not perform the optimization. This can |
| 145 | +keep your code compiling if you run into a problem, but the longer-term fix is |
| 146 | +to use a `#[repr]` attribute to guarantee a particular layout if you rely on it. |
| 147 | + |
| 148 | +We've been planning on moving `rustdoc` to use a CommonMark compliant markdown |
| 149 | +parser for a long time now. However, just switching over can introduce |
| 150 | +regressions where the CommonMark spec differs from our existing parser, Hoedown. |
| 151 | +As part of the transition plan, [a new flag has been added to |
| 152 | +`rustdoc`](https://github.com/rust-lang/rust/pull/40338), `--enable-commonmark`. |
| 153 | +This will use the new parser instead of the old one. Please give it a try! There's |
| 154 | +no scenario we know of where tweaking your markdown gets identical results on both |
| 155 | +parsers. |
| 156 | + |
| 157 | +Finally, compiling `rustc` itself is now [15%-20% faster](https://github.com/rust-lang/rust/pull/41469). Each commit message in this PR |
| 158 | +goes over the details, but the short of it is that there were some inefficient |
| 159 | +things, and now they've been cleaned up. |
| 160 | + |
| 161 | +See the [detailed release notes][notes] for more. |
| 162 | + |
| 163 | +#### Library stabilizations |
| 164 | + |
| 165 | +Seven new APIs were stabilized this release: |
| 166 | + |
| 167 | +- [`Child::try_wait`] is a non-blocking form of `Child::wait`. |
| 168 | +- [`HashMap::retain`] and [`HashSet::retain`] bring the `retain` API `Vec<T>` has to these two hash data structures. |
| 169 | +- [`PeekMut::pop`] lets you pop stuff off of a `BinaryHeap<T>` |
| 170 | +- [`TcpStream::peek`], [`UdpSocket::peek`], [`UdpSocket::peek_from`] let you peek at a stream or socket. |
| 171 | + |
| 172 | +[`Child::try_wait`]: https://doc.rust-lang.org/std/process/struct.Child.html#method.try_wait |
| 173 | +[`HashMap::retain`]: https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.retain |
| 174 | +[`HashSet::retain`]: https://doc.rust-lang.org/std/collections/struct.HashSet.html#method.retain |
| 175 | +[`PeekMut::pop`]: https://doc.rust-lang.org/std/collections/binary_heap/struct.PeekMut.html#method.pop |
| 176 | +[`TcpStream::peek`]: https://doc.rust-lang.org/std/net/struct.TcpStream.html#method.peek |
| 177 | +[`UdpSocket::peek_from`]: https://doc.rust-lang.org/std/net/struct.UdpSocket.html#method.peek_from |
| 178 | +[`UdpSocket::peek`]: https://doc.rust-lang.org/std/net/struct.UdpSocket.html#method.peek |
| 179 | + |
| 180 | +See the [detailed release notes][notes] for more. |
| 181 | + |
| 182 | +#### Cargo features |
| 183 | + |
| 184 | +Cargo has [added support](https://github.com/rust-lang/cargo/pull/3842) for the Pijul VCS, |
| 185 | +which is written in Rust. `cargo new my-awesome-project --vcs=pijul` will get you going! |
| 186 | + |
| 187 | +To suppliment the `--all` flag, Cargo now has [several new |
| 188 | +flags](https://github.com/rust-lang/cargo/pull/3901) such as `--bins`, |
| 189 | +`--examples`, `--tests`, and `--benches`, which will let you build all programs of |
| 190 | +that type. |
| 191 | + |
| 192 | +Finally, Cargo now supports [Haiku](https://github.com/rust-lang/cargo/pull/3952) and |
| 193 | +[Android](https://github.com/rust-lang/cargo/pull/3885)! |
| 194 | + |
| 195 | +See the [detailed release notes][notes] for more. |
| 196 | + |
| 197 | +### Contributors to 1.18.0 |
| 198 | + |
| 199 | +Many people came together to create Rust 1.18. We couldn't have done it without |
| 200 | +all of you. [Thanks!](https://thanks.rust-lang.org/rust/1.18.0) |
0 commit comments