|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Announcing Rust 1.38.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.38.0. Rust is a programming language that is empowering everyone to build reliable and efficient software. |
| 9 | + |
| 10 | +If you have a previous version of Rust installed via rustup, getting Rust 1.38.0 is as easy as: |
| 11 | + |
| 12 | +```console |
| 13 | +rustup update stable |
| 14 | +``` |
| 15 | + |
| 16 | +If you don't have it already, you can [get `rustup`][install] from the appropriate page on our website. |
| 17 | + |
| 18 | +[install]: https://www.rust-lang.org/install.html |
| 19 | + |
| 20 | +## What's in 1.38.0 stable |
| 21 | + |
| 22 | +### Pipelined compilation |
| 23 | + |
| 24 | +[internals-pipelined]: https://internals.rust-lang.org/t/evaluating-pipelined-rustc-compilation/10199 |
| 25 | + |
| 26 | +To compile a crate, the compiler doesn't need the dependencies to be fully built. Instead, it just needs their "metadata" (i.e. the list of types, dependencies, exports...). This metadata is produced early in the compilation process. Starting with Rust 1.38.0, Cargo will take advantage of this by automatically starting to build dependent crates as soon as metadata is ready. |
| 27 | + |
| 28 | +While the change doesn't have any effect on builds for a single crate, during testing [we got reports][internals-pipelined] of 10-20% compilation speed increases for optimized, clean builds of some crate graphs. Other ones did not improve much, and the speedup depends on the hardware running the build, so your mileage might vary. No code changes are needed to benefit from this. |
| 29 | + |
| 30 | +### Linting some incorrect uses of `mem::{uninitialized, zeroed}` |
| 31 | + |
| 32 | +As [previously announced](https://blog.rust-lang.org/2019/07/04/Rust-1.36.0.html#maybeuninitt%3E-instead-of-mem::uninitialized), `std::mem::uninitialized` is essentially impossible to use safely. Instead, `MaybeUninit<T>` should be used. |
| 33 | + |
| 34 | +We have not yet deprecated `mem::uninitialized`; this will be done in a future release. Starting in 1.38.0, however, `rustc` will provide a lint for a narrow class of incorrect initializations using `mem::uninitialized` or `mem::zeroed`. |
| 35 | + |
| 36 | +It is undefined behavior for some types, such as `&T` and `Box<T>`, to ever contain an all-`0` bit pattern, because they represent pointer-like objects that cannot be `null`. It is therefore an error to use `mem::uninitialized` or `mem::zeroed` to initialize one of these types, so the new lint will attempt to warn whenever one of those functions is used to initialize one of them, either directly or as a member of a larger `struct`. The check is recursive, so the following code will emit a warning: |
| 37 | + |
| 38 | +```rust |
| 39 | +struct Wrap<T>(T); |
| 40 | +struct Outer(Wrap<Wrap<Wrap<Box<i32>>>>); |
| 41 | +struct CannotBeZero { |
| 42 | + outer: Outer, |
| 43 | + foo: i32, |
| 44 | + bar: f32 |
| 45 | +} |
| 46 | + |
| 47 | +... |
| 48 | + |
| 49 | +let bad_value: CannotBeZero = unsafe { std::mem::uninitialized() }; |
| 50 | +``` |
| 51 | + |
| 52 | +Astute readers may note that Rust has more types that cannot be zero, notably `NonNull<T>` and `NonZero<T>`. For now, initialization of these structs with `mem::uninitialized` or `mem::zeroed` is *not* linted against. |
| 53 | + |
| 54 | +These checks do not cover all cases of unsound use of `mem::uninitialized` or `mem::zeroed`, they merely help identify code that is definitely wrong. All code should still be moved to use `MaybeUninit` instead. |
| 55 | + |
| 56 | +### `#[deprecated]` macros |
| 57 | + |
| 58 | +The `#[deprecated]` attribute, first introduced in Rust 1.9.0, allows crate authors to notify their users an item of their crate is deprecated and will be removed in a future release. Rust 1.38.0 extends the attribute, allowing it to be applied to macros as well. |
| 59 | + |
| 60 | +### `std::any::type_name` |
| 61 | + |
| 62 | +For debugging, it is sometimes useful to get the name of a type. For instance, in generic code, you may want to see, at run-time, what concrete types a function's type parameters has been instantiated with. This can now be done using `std::any::type_name`: |
| 63 | + |
| 64 | +```rust |
| 65 | +fn gen_value<T: Default>() -> T { |
| 66 | + println!("Initializing an instance of {}", std::any::type_name::<T>()); |
| 67 | + Default::default() |
| 68 | +} |
| 69 | + |
| 70 | +fn main() { |
| 71 | + let _: i32 = gen_value(); |
| 72 | + let _: String = gen_value(); |
| 73 | +} |
| 74 | +``` |
| 75 | + |
| 76 | +This prints: |
| 77 | + |
| 78 | +```text |
| 79 | +Initializing an instance of i32 |
| 80 | +Initializing an instance of alloc::string::String |
| 81 | +``` |
| 82 | + |
| 83 | +Like all standard library functions intended only for debugging, the exact contents and format of the string are not guaranteed. The value returned is only a best-effort description of the type; multiple types may share the same `type_name` value, and the value may change in future compiler releases. |
| 84 | + |
| 85 | +### Library changes |
| 86 | + |
| 87 | +- [`slice::{concat, connect, join}` now accepts `&[T]` in addition to `&T`.][62528] |
| 88 | +- [`*const T` and `*mut T` now implement `marker::Unpin`.][62583] |
| 89 | +- [`Arc<[T]>` and `Rc<[T]>` now implement `FromIterator<T>`.][61953] |
| 90 | +- [`iter::{StepBy, Peekable, Take}` now implement `DoubleEndedIterator`.][61457] |
| 91 | + |
| 92 | +Additionally, these functions have been stabilized: |
| 93 | + |
| 94 | +- [`<*const T>::cast`] and [`<*mut T>::cast`] |
| 95 | +- [`Duration::as_secs_f32`] and [`Duration::as_secs_f64`] |
| 96 | +- [`Duration::div_duration_f32`] and [`Duration::div_duration_f64`] |
| 97 | +- [`Duration::div_f32`] and [`Duration::div_f64`] |
| 98 | +- [`Duration::from_secs_f32`] and [`Duration::from_secs_f64`] |
| 99 | +- [`Duration::mul_f32`] and [`Duration::mul_f64`] |
| 100 | +- Euclidean remainder and division operations -- [`div_euclid`], |
| 101 | + [`rem_euclid`] -- for all integer primitives. `checked`, |
| 102 | + `overflowing`, and `wrapping` versions are also available. |
| 103 | + |
| 104 | +[`<*const T>::cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast |
| 105 | +[`<*mut T>::cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast-1 |
| 106 | +[`Duration::as_secs_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs_f32 |
| 107 | +[`Duration::as_secs_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs_f64 |
| 108 | +[`Duration::div_duration_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_duration_f32 |
| 109 | +[`Duration::div_duration_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_duration_f64 |
| 110 | +[`Duration::div_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_f32 |
| 111 | +[`Duration::div_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_f64 |
| 112 | +[`Duration::from_secs_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.from_secs_f32 |
| 113 | +[`Duration::from_secs_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.from_secs_f64 |
| 114 | +[`Duration::mul_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f32 |
| 115 | +[`Duration::mul_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f64 |
| 116 | +[`div_euclid`]: https://doc.rust-lang.org/std/primitive.i32.html#method.div_euclid |
| 117 | +[`rem_euclid`]: https://doc.rust-lang.org/std/primitive.i32.html#method.rem_euclid |
| 118 | + |
| 119 | + |
| 120 | +[62528]: https://github.com/rust-lang/rust/pull/62528/ |
| 121 | +[62583]: https://github.com/rust-lang/rust/pull/62583/ |
| 122 | +[61953]: https://github.com/rust-lang/rust/pull/61953/ |
| 123 | +[61884]: https://github.com/rust-lang/rust/pull/61884/ |
| 124 | +[61457]: https://github.com/rust-lang/rust/pull/61457/ |
| 125 | + |
| 126 | +### Other changes |
| 127 | + |
| 128 | +[relnotes-rust]: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1380-2019-09-26 |
| 129 | +[relnotes-cargo]: https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-138-2019-09-26 |
| 130 | +[relnotes-clippy]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-138 |
| 131 | + |
| 132 | +There are other changes in the Rust 1.38 release: check out what changed in [Rust][relnotes-rust], [Cargo][relnotes-cargo], and [Clippy][relnotes-clippy]. |
| 133 | + |
| 134 | +## Contributors to 1.38.0 |
| 135 | + |
| 136 | +Many people came together to create Rust 1.38.0. We couldn't have done it |
| 137 | +without all of you. [Thanks!](https://thanks.rust-lang.org/rust/1.38.0/) |
0 commit comments