|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Announcing Rust 1.41.0" |
| 4 | +author: The Rust Release Team |
| 5 | +release: true |
| 6 | +--- |
| 7 | + |
| 8 | +The Rust team is happy to announce a new version of Rust, 1.41.0. Rust is a |
| 9 | +programming language that is empowering everyone to build reliable and |
| 10 | +efficient software. |
| 11 | + |
| 12 | +If you have a previous version of Rust installed via rustup, getting Rust |
| 13 | +1.41.0 is as easy as: |
| 14 | + |
| 15 | +```console |
| 16 | +rustup update stable |
| 17 | +``` |
| 18 | + |
| 19 | +If you don't have it already, you can [get `rustup`][install] from the |
| 20 | +appropriate page on our website, and check out the [detailed release notes for |
| 21 | +1.41.0][notes] on GitHub. |
| 22 | + |
| 23 | +[install]: https://www.rust-lang.org/install.html |
| 24 | +[notes]: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1410-2020-01-30 |
| 25 | + |
| 26 | +## What's in 1.41.0 stable |
| 27 | + |
| 28 | +The highlights of Rust 1.41.0 include relaxed restrictions for trait |
| 29 | +implementations, improvements to `cargo install`, a more `git`-friendly |
| 30 | +`Cargo.lock`, and new FFI-related guarantees for `Box<T>`. See the [detailed |
| 31 | +release notes][notes] to learn about other changes not covered by this post. |
| 32 | + |
| 33 | +### Relaxed restrictions when implementing traits |
| 34 | + |
| 35 | +[book_orphan]: https://doc.rust-lang.org/book/ch10-02-traits.html#implementing-a-trait-on-a-type |
| 36 | +[ref_orphan]: https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence |
| 37 | +[book_newtype]: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#using-the-newtype-pattern-to-implement-external-traits-on-external-types |
| 38 | +[report_orphan]: https://github.com/rust-lang/rust/issues/63599 |
| 39 | +[rfc_orphan]: https://rust-lang.github.io/rfcs/2451-re-rebalancing-coherence.html |
| 40 | + |
| 41 | +To prevent breakages in the ecosystem when a dependency adds a new trait |
| 42 | +`impl`, Rust enforces the [*orphan rule*][book_orphan]. The gist of it is that |
| 43 | +a trait `impl` is only allowed if either the trait or the type being |
| 44 | +implemented is *local* to (defined in) the current crate as opposed to a |
| 45 | +*foreign* crate. [What this means exactly][ref_orphan] is complicated, however, |
| 46 | +when generics are involved. |
| 47 | + |
| 48 | +Before Rust 1.41.0, the orphan rule was unnecessarily strict, getting in the |
| 49 | +way of composition. As an example, suppose your crate defines the |
| 50 | +`BetterVec<T>` struct, and you want a way to convert your struct to the |
| 51 | +standard library's `Vec<T>`. The code you would write is: |
| 52 | + |
| 53 | +```rust |
| 54 | +impl<T> From<BetterVec<T>> for Vec<T> { |
| 55 | + // ... |
| 56 | +} |
| 57 | +``` |
| 58 | + |
| 59 | +...which is an instance of the pattern: |
| 60 | + |
| 61 | +```rust |
| 62 | +impl<T> ForeignTrait<LocalType> for ForeignType<T> { |
| 63 | + // ... |
| 64 | +} |
| 65 | +``` |
| 66 | + |
| 67 | +In Rust 1.40.0 this `impl` was forbidden by the orphan rule, as both `From` and |
| 68 | +`Vec` are defined in the standard library, which is foreign to the current |
| 69 | +crate. There were ways to work around the limitation, such as [the *newtype* |
| 70 | +pattern][book_newtype], but they were often cumbersome or even impossible in |
| 71 | +some cases. |
| 72 | + |
| 73 | +While it's still true that both `From` and `Vec` were foreign, the trait (in |
| 74 | +this case `From`) was parameterized by a local type. Therefore, Rust 1.41.0 |
| 75 | +allows this `impl`. |
| 76 | + |
| 77 | +For more details, read the [the stabilization report][report_orphan] and [the |
| 78 | +RFC proposing the change][rfc_orphan]. |
| 79 | + |
| 80 | +### `cargo install` updates packages when outdated |
| 81 | + |
| 82 | +With `cargo install`, you can install binary crates in your system. The command |
| 83 | +is often used by the community to install popular CLI tools written in Rust. |
| 84 | + |
| 85 | +Starting from Rust 1.41.0, `cargo install` will also update existing |
| 86 | +installations of the crate if a new release came out since you installed it. |
| 87 | +Before this release the only option was to pass the `--force` flag, which |
| 88 | +reinstalls the binary crate even if it's up to date. |
| 89 | + |
| 90 | +### Less conflict-prone `Cargo.lock` format |
| 91 | + |
| 92 | +To ensure consistent builds, Cargo uses a file named `Cargo.lock`, containing |
| 93 | +dependency versions and checksums. Unfortunately, the way the data was arranged |
| 94 | +in it caused unnecessary merge conflicts when changing dependencies in separate |
| 95 | +branches. |
| 96 | + |
| 97 | +Rust 1.41.0 introduces a new format for the file, explicitly designed to avoid |
| 98 | +those conflicts. This new format will be used for all new lockfiles, while |
| 99 | +existing lockfiles will still rely on the previous format. You can learn about |
| 100 | +the choices leading to the new format [in the PR adding it][cargo/7070]. |
| 101 | + |
| 102 | +[cargo/7070]: https://github.com/rust-lang/cargo/pull/7070 |
| 103 | + |
| 104 | +### More guarantees when using `Box<T>` in FFI |
| 105 | + |
| 106 | +[box_docs]: https://doc.rust-lang.org/std/boxed/index.html |
| 107 | + |
| 108 | +Starting with Rust 1.41.0, we have declared that a `Box<T>`, where `T: Sized` |
| 109 | +is now ABI compatible with the C language's pointer (`T*`) types. So if you |
| 110 | +have an `extern "C"` Rust function, called from C, your Rust function can now |
| 111 | +use `Box<T>`, for some specific `T`, while using `T*` in C for the |
| 112 | +corresponding function. As an example, on the C side you may have: |
| 113 | + |
| 114 | +```c |
| 115 | +// C header */ |
| 116 | + |
| 117 | +// Returns ownership to the caller. |
| 118 | +struct Foo* foo_new(void); |
| 119 | + |
| 120 | +// Takes ownership from the caller; no-op when invoked with NULL. |
| 121 | +void foo_delete(struct Foo*); |
| 122 | +``` |
| 123 | +
|
| 124 | +...while on the Rust side, you would have: |
| 125 | +
|
| 126 | +```rust |
| 127 | +#[repr(C)] |
| 128 | +pub struct Foo; |
| 129 | +
|
| 130 | +#[no_mangle] |
| 131 | +pub extern "C" fn foo_new() -> Box<Foo> { |
| 132 | + Box::new(Foo) |
| 133 | +} |
| 134 | +
|
| 135 | +// The possibility of NULL is represented with the `Option<_>`. |
| 136 | +#[no_mangle] |
| 137 | +pub extern "C" fn foo_delete(_: Option<Box<Foo>>) {} |
| 138 | +``` |
| 139 | + |
| 140 | +Note however that while `Box<T>` and `T*` have the same representation and ABI, |
| 141 | +a `Box<T>` must still be non-null, aligned, and ready for deallocation by the |
| 142 | +global allocator. To ensure this, it is best to only use `Box`es originating |
| 143 | +from the global allocator. |
| 144 | + |
| 145 | +**Important:** At least at present, you should avoid using `Box<T>` types for |
| 146 | +functions that are defined in C but invoked from Rust. In those cases, you |
| 147 | +should directly mirror the C types as closely as possible. Using types like |
| 148 | +`Box<T>` where the C definition is just using `T*` can lead to undefined |
| 149 | +behavior. |
| 150 | + |
| 151 | +To read more, [consult the documentation for `Box<T>`][box_docs]. |
| 152 | + |
| 153 | +### Library changes |
| 154 | + |
| 155 | +[`Result::map_or`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_or |
| 156 | +[`Result::map_or_else`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_or_else |
| 157 | +[`Option::map_or`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.map_or |
| 158 | +[`Option::map_or_else`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.map_or_else |
| 159 | +[`std::rc::Weak::weak_count`]: https://doc.rust-lang.org/std/rc/struct.Weak.html#method.weak_count |
| 160 | +[`std::rc::Weak::strong_count`]: https://doc.rust-lang.org/std/rc/struct.Weak.html#method.strong_count |
| 161 | +[`std::sync::Weak::weak_count`]: https://doc.rust-lang.org/std/sync/struct.Weak.html#method.weak_count |
| 162 | +[`std::sync::Weak::strong_count`]: https://doc.rust-lang.org/std/sync/struct.Weak.html#method.strong_count |
| 163 | +[pr_66277]: https://github.com/rust-lang/rust/pull/66277 |
| 164 | +[pr_65013]: https://github.com/rust-lang/rust/pull/65013 |
| 165 | + |
| 166 | +In Rust 1.41.0, we've made the following additions to the standard library: |
| 167 | + |
| 168 | +- The [`Result::map_or`] and [`Result::map_or_else`] methods were stabilized. |
| 169 | + |
| 170 | + Similar to [`Option::map_or`] and [`Option::map_or_else`], these methods are |
| 171 | + shorthands for the `.map(|val| process(val)).unwrap_or(default)` pattern. |
| 172 | + |
| 173 | +- [`NonZero*` numerics now implement `From<NonZero*>` if it's a smaller integer |
| 174 | + width.][pr_66277] For example, `NonZeroU16` now implements `From<NonZeroU8>`. |
| 175 | + |
| 176 | +- The `weak_count` and `strong_count` methods on `Weak` pointers were stabilized. |
| 177 | + |
| 178 | + - [`std::rc::Weak::weak_count`] |
| 179 | + - [`std::rc::Weak::strong_count`] |
| 180 | + - [`std::sync::Weak::weak_count`] |
| 181 | + - [`std::sync::Weak::strong_count`] |
| 182 | + |
| 183 | + These methods return the number of weak (`rc::Weak<T>` and `sync::Weak<T>`) |
| 184 | + or strong (`Rc<T>` and `Arc<T>`) pointers to the allocation respectively. |
| 185 | + |
| 186 | +- [`MaybeUninit<T>` now implements `fmt::Debug`.][pr_65013] |
| 187 | + |
| 188 | +### Reducing support for 32-bit Apple targets soon |
| 189 | + |
| 190 | +Rust 1.41.0 is the last release with the current level of compiler support for |
| 191 | +32-bit Apple targets, including the `i686-apple-darwin` target. Starting from |
| 192 | +Rust 1.42.0, these targets will be demoted to the lowest support tier. |
| 193 | + |
| 194 | +[You can learn more about this change in this blog post.][32bit-demotion] |
| 195 | + |
| 196 | +[32bit-demotion]: https://blog.rust-lang.org/2020/01/03/reducing-support-for-32-bit-apple-targets.html |
| 197 | + |
| 198 | +### Other changes |
| 199 | + |
| 200 | +[relnotes-cargo]: https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-141-2020-01-30 |
| 201 | +[relnotes-clippy]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-141 |
| 202 | +[mir-opt]: https://blog.rust-lang.org/inside-rust/2019/12/02/const-prop-on-by-default.html |
| 203 | + |
| 204 | +There are other changes in the Rust 1.41.0 release: check out what changed in |
| 205 | +[Rust][notes], [Cargo][relnotes-cargo], and [Clippy][relnotes-clippy]. We also |
| 206 | +have started landing MIR optimizations, which should improve compile time: you |
| 207 | +can learn more about them in the ["Inside Rust" blog post][mir-opt]. |
| 208 | + |
| 209 | +## Contributors to 1.41.0 |
| 210 | + |
| 211 | +Many people came together to create Rust 1.41.0. We couldn't have done it |
| 212 | +without all of you. [Thanks!](https://thanks.rust-lang.org/rust/1.41.0/) |
0 commit comments