|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Announcing Rust 1.41.1" |
| 4 | +author: The Rust Release Team |
| 5 | +release: true |
| 6 | +--- |
| 7 | + |
| 8 | +The Rust team has published a new point release of Rust, 1.41.1. |
| 9 | +Rust is a programming language that is empowering everyone to build reliable and efficient software. |
| 10 | + |
| 11 | +If you have a previous version of Rust installed via rustup, getting Rust 1.41.1 is as easy as: |
| 12 | + |
| 13 | +```console |
| 14 | +rustup update stable |
| 15 | +``` |
| 16 | + |
| 17 | +If you don't have it already, you can [get `rustup`][install] from the appropriate page on our website. |
| 18 | + |
| 19 | +[install]: https://www.rust-lang.org/tools/install |
| 20 | + |
| 21 | +## What's in 1.41.1 stable |
| 22 | + |
| 23 | +Rust 1.41.1 addresses two critical regressions introduced in Rust 1.41.0: |
| 24 | +a soundness hole related to static lifetimes, and a miscompilation causing segfaults. |
| 25 | +These regressions do not affect earlier releases of Rust, |
| 26 | +and we recommend users of Rust 1.41.0 to upgrade as soon as possible. |
| 27 | +Another issue related to interactions between `'static` and `Copy` implementations, |
| 28 | +dating back to Rust 1.0, was also addressed by this release. |
| 29 | + |
| 30 | +### A soundness hole in checking `static` items |
| 31 | + |
| 32 | +In Rust 1.41.0, due to some changes in the internal representation of `static` values, |
| 33 | +the borrow checker accidentally allowed some unsound programs. |
| 34 | +Specifically, the borrow checker would not check that `static` items had the correct type. |
| 35 | +This in turn would allow the assignment of a temporary, |
| 36 | +with a lifetime less than `'static`, to a `static` variable: |
| 37 | + |
| 38 | +```rust |
| 39 | +static mut MY_STATIC: &'static u8 = &0; |
| 40 | + |
| 41 | +fn main() { |
| 42 | + let my_temporary = 42; |
| 43 | + unsafe { |
| 44 | + // Erroneously allowed in 1.41.0: |
| 45 | + MY_STATIC = &my_temporary; |
| 46 | + } |
| 47 | +} |
| 48 | +``` |
| 49 | + |
| 50 | +This was addressed in 1.41.1, with the program failing to compile: |
| 51 | +``` |
| 52 | +error[E0597]: `my_temporary` does not live long enough |
| 53 | + --> src/main.rs:6:21 |
| 54 | + | |
| 55 | +6 | MY_STATIC = &my_temporary; |
| 56 | + | ------------^^^^^^^^^^^^^ |
| 57 | + | | | |
| 58 | + | | borrowed value does not live long enough |
| 59 | + | assignment requires that `my_temporary` is borrowed for `'static` |
| 60 | +7 | } |
| 61 | +8 | } |
| 62 | + | - `my_temporary` dropped here while still borrowed |
| 63 | +
|
| 64 | +``` |
| 65 | + |
| 66 | +You can learn more about this bug in [issue #69114][69114] and the [PR that fixed it][pr_69145]. |
| 67 | + |
| 68 | +[69114]: https://github.com/rust-lang/rust/issues/69114 |
| 69 | +[pr_69145]: https://github.com/rust-lang/rust/pull/69145 |
| 70 | + |
| 71 | +### Respecting a `'static` lifetime in a `Copy` implementation |
| 72 | + |
| 73 | +[1.40.0_post]: https://blog.rust-lang.org/2019/12/19/Rust-1.40.0.html#borrow-check-migration-warnings-are-hard-errors-in-rust-2015 |
| 74 | + |
| 75 | +Ever since Rust 1.0, the following erroneous program has been compiling: |
| 76 | + |
| 77 | +```rust |
| 78 | +#[derive(Clone)] |
| 79 | +struct Foo<'a>(&'a u32); |
| 80 | +impl Copy for Foo<'static> {} |
| 81 | + |
| 82 | +fn main() { |
| 83 | + let temporary = 2; |
| 84 | + let foo = (Foo(&temporary),); |
| 85 | + drop(foo.0); // Accessing a part of `foo` is necessary. |
| 86 | + drop(foo.0); // Indexing an array would also work. |
| 87 | +} |
| 88 | +``` |
| 89 | + |
| 90 | +In Rust 1.41.1, this issue was fixed [by the same PR as the one above][pr_69145]. |
| 91 | +Compiling the program now produces the following error: |
| 92 | + |
| 93 | +```rust |
| 94 | + |
| 95 | +error[E0597]: `temporary` does not live long enough |
| 96 | + --> src/main.rs:7:20 |
| 97 | + | |
| 98 | +7 | let foo = (Foo(&temporary),); |
| 99 | + | ^^^^^^^^^^ borrowed value does not live long enough |
| 100 | +8 | drop(foo.0); |
| 101 | + | ----- copying this value requires that |
| 102 | + | `temporary` is borrowed for `'static` |
| 103 | +9 | drop(foo.0); |
| 104 | +10 | } |
| 105 | + | - `temporary` dropped here while still borrowed |
| 106 | +``` |
| 107 | + |
| 108 | +This error occurs because `Foo<'a>`, for some `'a`, only implements `Copy` when `'a: 'static`. |
| 109 | +However, the `temporary` variable, |
| 110 | +with some lifetime `'0` does not outlive `'static` and hence `Foo<'0>` is not `Copy`, |
| 111 | +so using `drop` the second time around should be an error. |
| 112 | + |
| 113 | +### Miscompiled bound checks leading to segfaults |
| 114 | + |
| 115 | +In a few cases, programs compiled with Rust 1.41.0 were omitting bound checks in the memory allocation code. |
| 116 | +This caused segfaults if out of bound values were provided. |
| 117 | +The root cause of the miscompilation was a change in a LLVM optimization pass, |
| 118 | +introduced in LLVM 9 and reverted in LLVM 10. |
| 119 | + |
| 120 | +Rust 1.41.0 uses a snapshot of LLVM 9, so we cherry-picked the revert into Rust 1.41.1, |
| 121 | +addressing the miscompilation. [You can learn more about this bug in issue #69225][69225]. |
| 122 | + |
| 123 | +[69225]: https://github.com/rust-lang/rust/issues/69225 |
| 124 | + |
| 125 | +## Contributors to 1.41.1 |
| 126 | + |
| 127 | +Many people came together to create Rust 1.41.1. |
| 128 | +We couldn't have done it without all of you. [Thanks!](https://thanks.rust-lang.org/rust/1.41.1/) |
0 commit comments