|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Announcing Rust 1.32.0" |
| 4 | +author: The Rust Release Team |
| 5 | +--- |
| 6 | + |
| 7 | +The Rust team is happy to announce a new version of Rust, 1.32.0. Rust is a |
| 8 | +programming language that is empowering everyone to build reliable and |
| 9 | +efficient software. |
| 10 | + |
| 11 | +If you have a previous version of Rust installed via rustup, getting Rust |
| 12 | +1.32.0 is as easy as: |
| 13 | + |
| 14 | +``` |
| 15 | +$ rustup update stable |
| 16 | +``` |
| 17 | + |
| 18 | +If you don't have it already, you can [get `rustup`][install] from the |
| 19 | +appropriate page on our website, and check out the [detailed release notes for |
| 20 | +1.32.0][notes] on GitHub. |
| 21 | + |
| 22 | +> As a small side note, `rustup` has seen some new releases lately! To update |
| 23 | +> `rustup` itself, run `rustup self update`. |
| 24 | +
|
| 25 | +[install]: https://www.rust-lang.org/install.html |
| 26 | +[notes]: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1320-2019-01-17 |
| 27 | + |
| 28 | +## What's in 1.32.0 stable |
| 29 | + |
| 30 | +Rust 1.32.0 has a few quality of life improvements, switches the default |
| 31 | +allocator, and makes additional functions `const`. Read on for a few |
| 32 | +highlights, or see the [detailed release notes][notes] for additional |
| 33 | +information. |
| 34 | + |
| 35 | +#### The `dbg` macro |
| 36 | + |
| 37 | +First up, a quality of life improvement. Are you a "print debugger"? If you are, and |
| 38 | +you've wanted to print out some value while working on some code, you have to do this: |
| 39 | + |
| 40 | +```rust |
| 41 | +let x = 5; |
| 42 | + |
| 43 | +println!("{:?}", x); |
| 44 | + |
| 45 | +// or maybe even this |
| 46 | +println!("{:#?}", x); |
| 47 | +``` |
| 48 | + |
| 49 | +This isn't the *largest* speed bump, but it is a lot of stuff to simply show the value of `x`. |
| 50 | +Additionally, there's no context here. If you have several of these `println!`s, it can be hard |
| 51 | +to tell which is which, unless you add your own context to each invocation, requiring even more work. |
| 52 | + |
| 53 | +In Rust 1.32.0, [we've added a new macro, |
| 54 | +`dbg!`](https://github.com/rust-lang/rust/pull/56395/), for this purpose: |
| 55 | + |
| 56 | +```rust |
| 57 | +fn main() { |
| 58 | + let x = 5; |
| 59 | + |
| 60 | + dbg!(x); |
| 61 | +} |
| 62 | +``` |
| 63 | + |
| 64 | +If you run this program, you'll see: |
| 65 | + |
| 66 | +```text |
| 67 | +[src/main.rs:4] x = 5 |
| 68 | +``` |
| 69 | + |
| 70 | +You get the file and line number of where this was invoked, as well as the |
| 71 | +name and value. Additionally, `println!` prints to the standard output, so |
| 72 | +you really should be using `eprintln!` to print to standard error. `dbg!` |
| 73 | +does the right thing and goes to `stderr`. |
| 74 | + |
| 75 | +It even works in more complex circumstances. Consider this factorial example: |
| 76 | + |
| 77 | +```rust |
| 78 | +fn factorial(n: u32) -> u32 { |
| 79 | + if n <= 1 { |
| 80 | + n |
| 81 | + } else { |
| 82 | + n * factorial(n - 1) |
| 83 | + } |
| 84 | +} |
| 85 | +``` |
| 86 | + |
| 87 | +If we wanted to debug this, we might write it like this with `eprintln!`: |
| 88 | + |
| 89 | +```rust |
| 90 | +fn factorial(n: u32) -> u32 { |
| 91 | + eprintln!("n: {}", n); |
| 92 | + |
| 93 | + if n <= 1 { |
| 94 | + eprintln!("n <= 1"); |
| 95 | + |
| 96 | + n |
| 97 | + } else { |
| 98 | + let n = n * factorial(n - 1); |
| 99 | + |
| 100 | + eprintln!("n: {}", n); |
| 101 | + |
| 102 | + n |
| 103 | + } |
| 104 | +} |
| 105 | +``` |
| 106 | + |
| 107 | +We want to log `n` on each iteration, as well as have some kind of context |
| 108 | +for each of the branches. We see this output for `factorial(4)`: |
| 109 | + |
| 110 | +```text |
| 111 | +n: 4 |
| 112 | +n: 3 |
| 113 | +n: 2 |
| 114 | +n: 1 |
| 115 | +n <= 1 |
| 116 | +n: 2 |
| 117 | +n: 6 |
| 118 | +n: 24 |
| 119 | +``` |
| 120 | + |
| 121 | +This is servicable, but not particularly great. Maybe we could work on how we |
| 122 | +print out the context to make it more clear, but now we're not debugging our code, |
| 123 | +we're figuring out how to make our debugging code better. |
| 124 | + |
| 125 | +Consider this version using `dbg!`: |
| 126 | + |
| 127 | +```rust |
| 128 | +fn factorial(n: u32) -> u32 { |
| 129 | + if dbg!(n <= 1) { |
| 130 | + dbg!(1) |
| 131 | + } else { |
| 132 | + dbg!(n * factorial(n - 1)) |
| 133 | + } |
| 134 | +} |
| 135 | +``` |
| 136 | + |
| 137 | +We simply wrap each of the various expressions we want to print with the macro. We |
| 138 | +get this output instead: |
| 139 | + |
| 140 | +```text |
| 141 | +[src/main.rs:3] n <= 1 = false |
| 142 | +[src/main.rs:3] n <= 1 = false |
| 143 | +[src/main.rs:3] n <= 1 = false |
| 144 | +[src/main.rs:3] n <= 1 = true |
| 145 | +[src/main.rs:4] 1 = 1 |
| 146 | +[src/main.rs:5] n * factorial(n - 1) = 2 |
| 147 | +[src/main.rs:5] n * factorial(n - 1) = 6 |
| 148 | +[src/main.rs:5] n * factorial(n - 1) = 24 |
| 149 | +[src/main.rs:11] factorial(4) = 24 |
| 150 | +``` |
| 151 | + |
| 152 | +Because the `dbg!` macro returns the value of what it's debugging, instead of |
| 153 | +`eprintln!` which returns `()`, we need to make *no* changes to the structure |
| 154 | +of our code. Additionally, we have *vastly* more useful output. |
| 155 | + |
| 156 | +That's a lot to say about a little macro, but we hope it improves your |
| 157 | +debugging experience! We are contining to work on support for `gdb` and |
| 158 | +friends as well, of course. |
| 159 | + |
| 160 | +#### `jemalloc` is removed by default |
| 161 | + |
| 162 | +Long, long ago, Rust had a large, Erlang-like runtime. We chose to use |
| 163 | +[jemalloc] instead of the system allocator, because it often improved |
| 164 | +performance over the default system one. Over time, we shed more and more of |
| 165 | +this runtime, and eventually almost all of it was removed, but jemalloc |
| 166 | +was not. We didn't have a way to choose a custom allocator, and so we |
| 167 | +couldn't really remove it without causing a regression for people who do need |
| 168 | +jemalloc. |
| 169 | + |
| 170 | +Also, saying that `jemalloc` was always the default is a bit UNIX-centric, |
| 171 | +as it was only the default on *some* platforms. Notably, the MSVC target on |
| 172 | +Windows has shipped the system allocator for a long time. |
| 173 | + |
| 174 | +Finally, while jemalloc *usually* has great performance, that's not always |
| 175 | +the case. Additionally, it adds about 300kb to every Rust binary. We've also |
| 176 | +had a host of [other |
| 177 | +issues](https://github.com/rust-lang/rust/issues/36963#issuecomment-252029017) |
| 178 | +with jemalloc in the past. It has also felt a little strange that a systems |
| 179 | +language does not default to the system's allocator. |
| 180 | + |
| 181 | +For all of these reasons, once [Rust 1.28 shipped a way to choose a global |
| 182 | +allocator](https://blog.rust-lang.org/2018/08/02/Rust-1.28.html#whats-in-1.28.0-stable), |
| 183 | +we started making plans to switch the default to the system allocator, and |
| 184 | +allow you to use `jemalloc` via a crate. In Rust 1.32, we've finally finished |
| 185 | +this work, and by default, you will get the system allocator for your |
| 186 | +programs. |
| 187 | + |
| 188 | +If you'd like to continue to use jemalloc, use [the jemallocator crate]. In |
| 189 | +your `Cargo.toml`: |
| 190 | + |
| 191 | +```toml |
| 192 | +jemallocator = "0.1.8" |
| 193 | +``` |
| 194 | + |
| 195 | +And in your crate root: |
| 196 | + |
| 197 | +```rust |
| 198 | +#[global_allocator] |
| 199 | +static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; |
| 200 | +``` |
| 201 | + |
| 202 | +That's it! If you don't need jemalloc, it's not forced upon you, and if |
| 203 | +you do need it, it's a few lines of code away. |
| 204 | + |
| 205 | +[jemalloc]: http://jemalloc.net/ |
| 206 | +[the jemallocator crate]: https://crates.io/crates/jemallocator |
| 207 | + |
| 208 | +#### Final module improvements |
| 209 | + |
| 210 | +In the past two releases, we announced several improvements to the module |
| 211 | +system. We have one last tweak landing in 1.32.0 and the 2018 edition. |
| 212 | +Nicknamed ["uniform |
| 213 | +paths"](https://github.com/rust-lang/rust/pull/56759#issuecomment-450051210), |
| 214 | +it permits previously invalid import path statements to be resolved exactly |
| 215 | +the same way as non-import paths. For example: |
| 216 | + |
| 217 | +```rust |
| 218 | +enum Color { Red, Green, Blue } |
| 219 | + |
| 220 | +use Color::*; |
| 221 | +``` |
| 222 | + |
| 223 | +This code did *not* previously compile, as `use` statements had to start with |
| 224 | +`super`, `self`, or `crate`. Now that the compiler supports uniform paths, |
| 225 | +this code will work, and do what you probably expect: import the variants of |
| 226 | +the `Color` enum defined above the `use` statement. |
| 227 | + |
| 228 | +With this change in place, we've completed our efforts at revising the module |
| 229 | +system. We hope you've been enjoying the simplified system so far! |
| 230 | + |
| 231 | + |
| 232 | +#### Macro improvements |
| 233 | + |
| 234 | +A few improvements to macros have landed in Rust 1.32.0. First, [a new |
| 235 | +`literal` matcher](https://github.com/rust-lang/rust/pull/56072/) was added: |
| 236 | + |
| 237 | +```rust |
| 238 | +macro_rules! m { |
| 239 | + ($lt:literal) => {}; |
| 240 | +} |
| 241 | + |
| 242 | +fn main() { |
| 243 | + m!("some string literal"); |
| 244 | +} |
| 245 | +``` |
| 246 | + |
| 247 | +`literal` mactches against literals of any type; string literals, numeric literals, `char` literals. |
| 248 | + |
| 249 | +In the 2018 edition, `macro_rules` macros can also use `?`, like this: |
| 250 | + |
| 251 | +```rust |
| 252 | +macro_rules! bar { |
| 253 | + ($(a)?) => {} |
| 254 | +} |
| 255 | +``` |
| 256 | + |
| 257 | +The `?` will match zero or one repetitions of the pattern, similar to the |
| 258 | +already-existing `*` for "zero or more" and `+` for "one or more." |
| 259 | + |
| 260 | +### Library stabilizations |
| 261 | + |
| 262 | +We talked above about the `dbg!` macro, which is a big library addition. |
| 263 | +Beyond that, 19 functions were made `const fn`s, and all integral numeric |
| 264 | +primitives now provide conversion functions to and from byte-arrays with |
| 265 | +specified edianness. These six functions are named `to_<endian>_bytes` and |
| 266 | +`from_<endian>_bytes`, where `<endian>` is one of: |
| 267 | + |
| 268 | +* `ne` - native endianness |
| 269 | +* `le` - little endian |
| 270 | +* `be` - big endian |
| 271 | + |
| 272 | +See the [detailed release notes][notes] for more details. |
| 273 | + |
| 274 | +### Cargo features |
| 275 | + |
| 276 | +Cargo gained [`cargo c` as an alias for `cargo |
| 277 | +check`](https://github.com/rust-lang/cargo/pull/6218/), and now [allows |
| 278 | +usernames in registry URLs](https://github.com/rust-lang/cargo/pull/6242/). |
| 279 | + |
| 280 | +See the [detailed release notes][notes] for more. |
| 281 | + |
| 282 | +## Contributors to 1.32.0 |
| 283 | + |
| 284 | +Many people came together to create Rust 1.32.0. We couldn't have done it |
| 285 | +without all of you. [Thanks!](https://thanks.rust-lang.org/rust/1.32.0) |
0 commit comments