|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Announcing Rust 1.15" |
| 4 | +author: The Rust Core Team |
| 5 | +--- |
| 6 | + |
| 7 | +The Rust team is happy to announce the latest version of Rust, 1.15.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.15 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.15.0][notes] on GitHub. 1443 patches were landed in this release. |
| 19 | + |
| 20 | +[install]: https://www.rust-lang.org/install.html |
| 21 | +[notes]: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1150-2017-02-02 |
| 22 | + |
| 23 | +### What's in 1.15.0 stable |
| 24 | + |
| 25 | +Rust 1.15 sees an _extremely_ eagerly-awaited feature land on stable: custom |
| 26 | +derive! To review, in Rust, you've always been able to automatically implement |
| 27 | +some traits through the `derive` attribute: |
| 28 | + |
| 29 | +```rust |
| 30 | +#[derive(Debug)] |
| 31 | +struct Pet { |
| 32 | + name: String, |
| 33 | +} |
| 34 | +``` |
| 35 | + |
| 36 | +The `Debug` trait is then implemented for `Pet`, with vastly less boilerplate. |
| 37 | +However, this only worked for traits provided as part of the standard library; |
| 38 | +it was not customizable. With Rust 1.15, it now is. That means, if you want to |
| 39 | +turn your `Pet` into JSON, it's as easy as adding [Serde][serde] to your |
| 40 | +`Cargo.toml`: |
| 41 | + |
| 42 | +```toml |
| 43 | +[dependencies] |
| 44 | +serde = "0.9" |
| 45 | +serde_derive = "0.9" |
| 46 | +serde_json = "0.9" |
| 47 | +``` |
| 48 | + |
| 49 | +[serde]: https://serde.rs |
| 50 | + |
| 51 | +And adding another trait to your `Pet`: |
| 52 | + |
| 53 | +```rust |
| 54 | +#[macro_use] |
| 55 | +extern crate serde_derive; |
| 56 | + |
| 57 | +extern crate serde_json; |
| 58 | + |
| 59 | +#[derive(Serialize, Deserialize, Debug)] |
| 60 | +struct Pet { |
| 61 | + name: String, |
| 62 | +} |
| 63 | + |
| 64 | +fn main() { |
| 65 | + let pet = Pet { name: String::from("Ferris") }; |
| 66 | + |
| 67 | + let serialized = serde_json::to_string(&pet).unwrap(); |
| 68 | + println!("serialized = {}", serialized); |
| 69 | + |
| 70 | + let deserialized: Pet = serde_json::from_str(&serialized).unwrap(); |
| 71 | + println!("deserialized = {:?}", deserialized); |
| 72 | +} |
| 73 | +``` |
| 74 | + |
| 75 | +This will output: |
| 76 | + |
| 77 | +```text |
| 78 | +serialized = {"name":"Ferris"} |
| 79 | +deserialized = Pet { name: "Ferris" } |
| 80 | +``` |
| 81 | + |
| 82 | +Another common use-case is [Diesel][diesel]. Say we had a database of `Pet`s. |
| 83 | +We could fetch them like this: |
| 84 | + |
| 85 | +```rust |
| 86 | +// some extern crate and use lines elided here |
| 87 | + |
| 88 | +#[derive(Queryable)] |
| 89 | +struct Pet { |
| 90 | + name: String, |
| 91 | +} |
| 92 | + |
| 93 | +fn main() { |
| 94 | + use diesel_demo::schema::pets::dsl::*; |
| 95 | + |
| 96 | + let connection = establish_connection(); |
| 97 | + let results = pets |
| 98 | + .limit(5) |
| 99 | + .load::<Pet>(&connection) |
| 100 | + .expect("Error loading pets"); |
| 101 | + |
| 102 | + println!("Displaying {} pets", results.len()); |
| 103 | + for pet in results { |
| 104 | + println!("{}", pet.name); |
| 105 | + } |
| 106 | +} |
| 107 | +``` |
| 108 | + |
| 109 | +For full instructions, see [the website][diesel]. |
| 110 | + |
| 111 | +[diesel]: http://diesel.rs |
| 112 | + |
| 113 | +These kinds of libraries are extremely powerful, but rely on custom derive for |
| 114 | +ergonomics. While these libraries _worked_ on Rust stable previously, they were |
| 115 | +not as nice to use, so much so that we often heard from users "I only use |
| 116 | +nightly because of Serde and Diesel." The use of custom derive is one of the |
| 117 | +most widely used nightly-only features. As such, [RFC 1681] was opened in July |
| 118 | +of last year to support this use-case. The RFC was merged in August, underwent |
| 119 | +a lot of development and testing, and now reaches stable today! |
| 120 | + |
| 121 | +[RFC 1681]: https://github.com/rust-lang/rfcs/pull/1681 |
| 122 | + |
| 123 | +To find out how to write your own custom derives, see [the chapter of "The Rust |
| 124 | +Programming Language"](https://doc.rust-lang.org/book/procedural-macros.html). |
| 125 | + |
| 126 | +While we've said "Serde and Diesel" a number of times here, there's a lot of |
| 127 | +other cool things you can do with custom derive: see |
| 128 | +[`derive-new`](https://crates.io/crates/derive-new) for another example. See |
| 129 | +[the `syn` crate's reverse dependencies for more.][syn-deps] (`syn` is |
| 130 | +important for writing custom derives, see the book chapter, linked above, for |
| 131 | +more.) Custom derive was also known as "macros 1.1", as it includes the |
| 132 | +infrastructure for supporting even more compile-time powers of Rust, nicknamed |
| 133 | +"macros 2.0." Expect to hear more about this space in future releases. |
| 134 | + |
| 135 | +[syn-deps]: https://crates.io/crates/syn/reverse_dependencies |
| 136 | + |
| 137 | +#### Other improvements |
| 138 | + |
| 139 | +The build system for Rust [has been re-written in Rust, using |
| 140 | +Cargo][rustbuild]. It is now the default. This process has been long, but has |
| 141 | +finally borne fruit. Given that all Rust development happens on the master |
| 142 | +branch, we've been using it since December of last year, and it's working well. |
| 143 | +There is an open PR [to remove the Makefiles entirely][rustbuild-only], landing |
| 144 | +in Rust 1.17. This will pave the way for `rustc` to use packages from |
| 145 | +`crates.io` in the compiler like any other Rust project, and is a further |
| 146 | +demonstration of the maturity of Cargo. |
| 147 | + |
| 148 | +[rustbuild]: https://github.com/rust-lang/rust/pull/37817 |
| 149 | +[rustbuild-only]: https://github.com/rust-lang/rust/pull/39431 |
| 150 | + |
| 151 | +Rust has gained [Tier 3 support][tiers] for [`i686-unknown-openbsd`], [`MSP430`], |
| 152 | +and [`ARMv5TE`]. |
| 153 | + |
| 154 | +[tiers]: https://forge.rust-lang.org/platform-support.html |
| 155 | +[`i686-unknown-openbsd`]: https://github.com/rust-lang/rust/pull/38086 |
| 156 | +[`MSP430`]: https://github.com/rust-lang/rust/pull/37627 |
| 157 | +[`ARMv5TE`]: https://github.com/rust-lang/rust/pull/37615 |
| 158 | + |
| 159 | +[A number of compiler performance improvements have |
| 160 | +landed](https://github.com/rust-lang/rust/blob/master/RELEASES.md#compiler-performance). |
| 161 | +We continue to work on making the compiler faster. Expect to see more in the |
| 162 | +future! |
| 163 | + |
| 164 | +As a smaller improvement, [`?Sized` can now be used in `where` |
| 165 | +clauses](https://github.com/rust-lang/rust/pull/37791). In other words: |
| 166 | + |
| 167 | +```rust |
| 168 | +struct Foo<T: ?Sized> { |
| 169 | + f: T, |
| 170 | +} |
| 171 | + |
| 172 | +struct Foo<T> where T: ?Sized { |
| 173 | + f: T, |
| 174 | +} |
| 175 | +``` |
| 176 | + |
| 177 | +This second form is now accepted, and is equivalent to the first. |
| 178 | + |
| 179 | + |
| 180 | +See the [detailed release notes][notes] for more. |
| 181 | + |
| 182 | +#### Library stabilizations |
| 183 | + |
| 184 | +The `slice::sort` algorithm [has been rewritten][38192], and is much, much, |
| 185 | +much faster. It is a hybrid merge sort, drawing influences from Timsort. |
| 186 | +Previously it was a straightforward merge sort. |
| 187 | + |
| 188 | +If you had a `Vec<T>` where `T: Copy`, and you called `extend` on it, |
| 189 | +your code will [now be a lot faster][38182]. |
| 190 | + |
| 191 | +Speaking of things getting faster, [`chars().count()`][37888], |
| 192 | +[`chars().last()`, and `char_indices().last()`][37882] are too! |
| 193 | + |
| 194 | +[Chinese characters now display correctly in `fmt::Debug`][37855]. |
| 195 | + |
| 196 | +[38192]: https://github.com/rust-lang/rust/pull/38192 |
| 197 | +[38182]: https://github.com/rust-lang/rust/pull/38182 |
| 198 | +[37888]: https://github.com/rust-lang/rust/pull/37888 |
| 199 | +[37882]: https://github.com/rust-lang/rust/pull/37882 |
| 200 | +[37855]: https://github.com/rust-lang/rust/pull/37855 |
| 201 | + |
| 202 | +There were a number of functions stabilized as well: |
| 203 | + |
| 204 | +* [`std::iter::Iterator::min_by`] and [`std::iter::Iterator::max_by`] |
| 205 | +* [`std::os::*::fs::FileExt`] |
| 206 | +* [`std::sync::atomic::Atomic*::get_mut`] and [`std::sync::atomic::Atomic*::into_inner`] |
| 207 | +* [`std::vec::IntoIter::as_slice`] and [`std::vec::IntoIter::as_mut_slice`] |
| 208 | +* [`std::sync::mpsc::Receiver::try_iter`] |
| 209 | +* [`std::os::unix::process::CommandExt::before_exec`] |
| 210 | +* [`std::rc::Rc::strong_count`] and [`std::rc::Rc::weak_count`] |
| 211 | +* [`std::sync::Arc::strong_count`] and [`std::sync::Arc::weak_count`] |
| 212 | +* [`std::char::encode_utf8`] and [`std::char::encode_utf16`] |
| 213 | +* [`std::cell::Ref::clone`] |
| 214 | +* [`std::io::Take::into_inner`] |
| 215 | + |
| 216 | +[`std::iter::Iterator::min_by`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.min_by |
| 217 | +[`std::iter::Iterator::max_by`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.max_by |
| 218 | +[`std::os::*::fs::FileExt`]: https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html |
| 219 | +[`std::sync::atomic::Atomic*::get_mut`]: https://doc.rust-lang.org/std/sync/atomic/struct.AtomicU8.html#method.get_mut |
| 220 | +[`std::sync::atomic::Atomic*::into_inner`]: https://doc.rust-lang.org/std/sync/atomic/struct.AtomicU8.html#method.into_inner |
| 221 | +[`std::vec::IntoIter::as_slice`]: https://doc.rust-lang.org/std/vec/struct.IntoIter.html#method.as_slice |
| 222 | +[`std::vec::IntoIter::as_mut_slice`]: https://doc.rust-lang.org/std/vec/struct.IntoIter.html#method.as_mut_slice |
| 223 | +[`std::sync::mpsc::Receiver::try_iter`]: https://doc.rust-lang.org/std/sync/mpsc/struct.Receiver.html#method.try_iter |
| 224 | +[`std::os::unix::process::CommandExt::before_exec`]: https://doc.rust-lang.org/std/os/unix/process/trait.CommandExt.html#tymethod.before_exec |
| 225 | +[`std::rc::Rc::strong_count`]: https://doc.rust-lang.org/std/rc/struct.Rc.html#method.strong_count |
| 226 | +[`std::rc::Rc::weak_count`]: https://doc.rust-lang.org/std/rc/struct.Rc.html#method.weak_count |
| 227 | +[`std::sync::Arc::strong_count`]: https://doc.rust-lang.org/std/sync/struct.Arc.html#method.strong_count |
| 228 | +[`std::sync::Arc::weak_count`]: https://doc.rust-lang.org/std/sync/struct.Arc.html#method.weak_count |
| 229 | +[`std::char::encode_utf8`]: https://doc.rust-lang.org/std/primitive.char.html#method.encode_utf8 |
| 230 | +[`std::char::encode_utf16`]: https://doc.rust-lang.org/std/primitive.char.html#method.encode_utf16 |
| 231 | +[`std::cell::Ref::clone`]: https://doc.rust-lang.org/std/cell/struct.Ref.html#method.clone |
| 232 | +[`std::io::Take::into_inner`]: https://doc.rust-lang.org/std/io/struct.Take.html#method.into_inner |
| 233 | + |
| 234 | +See the [detailed release notes][notes] for more. |
| 235 | + |
| 236 | +#### Cargo features |
| 237 | + |
| 238 | +Cargo will now [emit a warning][cargo/3361] if you have a file named `build.rs` |
| 239 | +at the top level of a package, but don't have a `build = "build.rs"` |
| 240 | +annotation. This is in anticipation of inferring that `build.rs` at the top |
| 241 | +level is always a build script, but is a warning right now for compatibility |
| 242 | +reasons. Previously, all build scripts required configuration, but this |
| 243 | +convention was strong within the community, so we're going to encode it into |
| 244 | +Cargo. |
| 245 | + |
| 246 | +[cargo/3361]: https://github.com/rust-lang/cargo/pull/3361 |
| 247 | + |
| 248 | +In this release, [Cargo build scripts no longer have access to the `OUT_DIR` |
| 249 | +environment variable at build time via `env!("OUT_DIR")`][cargo/3368]. They |
| 250 | +should instead check the variable at runtime with `std::env`. That the value |
| 251 | +was set at build time was a bug, and incorrect when cross-compiling. Please |
| 252 | +check what your packages are doing and update to use `std::env`! |
| 253 | + |
| 254 | +[cargo/3368]: https://github.com/rust-lang/cargo/pull/3368 |
| 255 | + |
| 256 | +The `cargo test` command has [gained support for a `--all` flag][cargo/3321], |
| 257 | +which is useful when you have a workspace. |
| 258 | + |
| 259 | +[cargo/3321]: https://github.com/rust-lang/cargo/pull/3321 |
| 260 | + |
| 261 | +We now [Compile statically against the MSVC CRT][cargo/3363] on Windows, and |
| 262 | +[Link OpenSSL statically][cargo/3311] on Mac OS X. |
| 263 | + |
| 264 | +[cargo/3363]: https://github.com/rust-lang/cargo/pull/3363 |
| 265 | +[cargo/3311]: https://github.com/rust-lang/cargo/pull/3311 |
| 266 | + |
| 267 | +See the [detailed release notes][notes] for more. |
| 268 | + |
| 269 | +### Contributors to 1.15.0 |
| 270 | + |
| 271 | +In this part of the release announcements, we usually post a list of |
| 272 | +contributors. However, we've recently started a new initiative, "Thanks!", to |
| 273 | +do this in a more comprehensive way. One issue with this section is that it |
| 274 | +only counted contributions to the `rust-lang/rust` repository; those who |
| 275 | +committed to Cargo weren't thanked, for example. We also had to manually |
| 276 | +generate this list, which wasn't terrible, but running the correct git commands |
| 277 | +to determine who contributed is exactly what code is good for! |
| 278 | + |
| 279 | +As such, you can now visit |
| 280 | +[https://thanks.rust-lang.org/](https://thanks.rust-lang.org/) to see more |
| 281 | +comprehensive contribution calculations. If you prefer, we also have an alias |
| 282 | +at [https://❤.rust-lang.org](https://❤.rust-lang.org) as well. For now, this |
| 283 | +will only show what we've shown in previous release posts. We do have one |
| 284 | +additional feature, which is an all-time contributions list, sorted by commit |
| 285 | +count. That's located here: |
| 286 | +[https://thanks.rust-lang.org/rust/all-time](https://thanks.rust-lang.org/rust/all-time) |
| 287 | + |
| 288 | +We have done some of the needed backend work to enable more repositories than |
| 289 | +only `rust-lang/rust`, but it's not quite done yet. If you'd like to get |
| 290 | +involved, please [check out thanks on |
| 291 | +GitHub](https://github.com/rust-lang-nursery/thanks)! |
| 292 | + |
| 293 | +We had 136 individuals contribute to Rust 1.15. |
| 294 | +[Thanks!](https://thanks.rust-lang.org/rust/1.15.0) |
0 commit comments