Skip to content

Commit 166987c

Browse files
committed
Blog post for Rust 1.58.0
1 parent 4a29d64 commit 166987c

File tree

1 file changed

+181
-0
lines changed

1 file changed

+181
-0
lines changed

posts/2022-01-13-Rust-1.58.0.md

+181
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
---
2+
layout: post
3+
title: "Announcing Rust 1.58.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.58.0.
9+
Rust is a programming language empowering everyone to build reliable and efficient software.
10+
11+
If you have a previous version of Rust installed via rustup, getting Rust 1.58.0 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]
18+
from the appropriate page on our website, and check out the
19+
[detailed release notes for 1.58.0][notes] on GitHub.
20+
21+
[install]: https://www.rust-lang.org/install.html
22+
[notes]: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1580-2022-01-13
23+
24+
## What's in 1.58.0 stable
25+
26+
Rust 1.58 brings captured identifiers in format strings, a change to the
27+
`Command` search path on Windows, more `#[must_use]` annotations in the
28+
standard library, and some new library stabilizations.
29+
30+
### Captured identifiers in format strings
31+
32+
Format strings can now capture arguments simply by writing `{ident}` in the
33+
string. Formats have long accepted positional arguments (optionally by index)
34+
and named arguments, for example:
35+
36+
```rust
37+
println!("Hello, {}!", get_person()); // implicit position
38+
println!("Hello, {0}!", get_person()); // explicit index
39+
println!("Hello, {person}!", person = get_person()); // named
40+
```
41+
42+
Now named arguments can also be captured from the surrounding scope, like:
43+
44+
```rust
45+
let person = get_person();
46+
// ...
47+
println!("Hello, {person}!"); // captures the local `person`
48+
```
49+
50+
This may also be used in formatting parameters:
51+
52+
```rust
53+
let (width, precision) = get_format();
54+
for (name, score) in get_scores() {
55+
println!("{name}: {score:width$.precision$}");
56+
}
57+
```
58+
59+
Format strings can only capture plain identifiers, not arbitrary paths or
60+
expressions. For more complicated arguments, either assign them to a local name
61+
first, or use the older `name = expression` style of formatting arguments.
62+
63+
This feature works in all macros accepting format strings. However, one corner
64+
case is the `panic!` macro in 2015 and 2018 editions, where `panic!("{ident}")`
65+
is still treated as an unformatted string -- the compiler will warn about this
66+
not having the intended effect.
67+
68+
### Reduced Windows `Command` search path
69+
70+
On Windows targets, `std::process::Command` will no longer search the current
71+
directory for executables. That effect was owed to historical behavior of the
72+
win32 [`CreateProcess`] API, so Rust was effectively searching in this order:
73+
74+
1. (Rust specific) The directories that are listed in the child's `PATH`
75+
environment variable, if it was explicitly changed from the parent.
76+
2. The directory from which the application loaded.
77+
3. The current directory for the parent process.
78+
4. The 32-bit Windows system directory.
79+
5. The 16-bit Windows system directory.
80+
6. The Windows directory.
81+
7. The directories that are listed in the `PATH` environment variable.
82+
83+
However, using the current directory can lead to surprising results, or even
84+
malicious behavior when dealing with untrusted directories. For example,
85+
`ripgrep` published [CVE-2021-3013] when they learned that their child
86+
processes could be intercepted in this way. Even Microsoft's own PowerShell
87+
[documents][PS] that they do not use the current directory for security.
88+
89+
Rust now performs its own search without the current directory, and the legacy
90+
16-bit directory is also not included, as there is no API to discover its
91+
location. So the new `Command` search order for Rust on Windows is:
92+
93+
1. The directories that are listed in the child's `PATH` environment variable.
94+
2. The directory from which the application loaded.
95+
3. The 32-bit Windows system directory.
96+
4. The Windows directory.
97+
5. The directories that are listed in the `PATH` environment variable.
98+
99+
Non-Windows targets continue to use their platform-specific behavior, most
100+
often only considering the child or parent `PATH` environment variable.
101+
102+
[`CreateProcess`]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa
103+
[CVE-2021-3013]: https://www.cve.org/CVERecord?id=CVE-2021-3013
104+
[PS]: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_command_precedence?view=powershell-7.2
105+
106+
### More `#[must_use]` in the standard library
107+
108+
The `#[must_use]` attribute can be applied to types or functions when failing
109+
to explicitly consider them or their output is almost certainly a bug. This has
110+
long been used in the standard library for types like `Result`, which should be
111+
checked for error conditions. This also helps catch mistakes such as expecting
112+
a function to mutate a value in-place, when it actually returns a new value.
113+
114+
Library [proposal 35] was approved in October 2021 to audit and expand the
115+
application of `#[must_use]` throughout the standard library, covering many
116+
more functions where the primary effect is the return value. This is similar
117+
to the idea of function purity, but looser than a true language feature. Some
118+
of these additions were present in release 1.57.0, and now in 1.58.0 the effort
119+
has completed.
120+
121+
[proposal 35]: https://github.com/rust-lang/libs-team/issues/35
122+
123+
### Stabilized APIs
124+
125+
The following methods and trait implementations were stabilized.
126+
127+
- [`Metadata::is_symlink`]
128+
- [`Path::is_symlink`]
129+
- [`{integer}::saturating_div`]
130+
- [`Option::unwrap_unchecked`]
131+
- [`Result::unwrap_unchecked`]
132+
- [`Result::unwrap_err_unchecked`]
133+
- [`NonZero{unsigned}::is_power_of_two`]
134+
135+
The following previously stable functions are now `const`.
136+
137+
- [`Duration::new`]
138+
- [`Duration::checked_add`]
139+
- [`Duration::saturating_add`]
140+
- [`Duration::checked_sub`]
141+
- [`Duration::saturating_sub`]
142+
- [`Duration::checked_mul`]
143+
- [`Duration::saturating_mul`]
144+
- [`Duration::checked_div`]
145+
- [`MaybeUninit::as_ptr`]
146+
- [`MaybeUninit::as_mut_ptr`]
147+
- [`MaybeUninit::assume_init`]
148+
- [`MaybeUninit::assume_init_ref`]
149+
150+
[`Metadata::is_symlink`]: https://doc.rust-lang.org/stable/std/fs/struct.Metadata.html#method.is_symlink
151+
[`Path::is_symlink`]: https://doc.rust-lang.org/stable/std/path/struct.Path.html#method.is_symlink
152+
[`{integer}::saturating_div`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.saturating_div
153+
[`Option::unwrap_unchecked`]: https://doc.rust-lang.org/stable/std/option/enum.Option.html#method.unwrap_unchecked
154+
[`Result::unwrap_unchecked`]: https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.unwrap_unchecked
155+
[`Result::unwrap_err_unchecked`]: https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.unwrap_err_unchecked
156+
[`NonZero{unsigned}::is_power_of_two`]: https://doc.rust-lang.org/stable/std/num/struct.NonZeroU8.html#method.is_power_of_two
157+
[`Duration::new`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.new
158+
[`Duration::checked_add`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.checked_add
159+
[`Duration::saturating_add`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.saturating_add
160+
[`Duration::checked_sub`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.checked_sub
161+
[`Duration::saturating_sub`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.saturating_sub
162+
[`Duration::checked_mul`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.checked_mul
163+
[`Duration::saturating_mul`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.saturating_mul
164+
[`Duration::checked_div`]: https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.checked_div
165+
[`MaybeUninit::as_ptr`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.as_ptr
166+
[`MaybeUninit::as_mut_ptr`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.as_mut_ptr
167+
[`MaybeUninit::assume_init`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init
168+
[`MaybeUninit::assume_init_ref`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init_ref
169+
170+
### Other changes
171+
172+
There are other changes in the Rust 1.58.0 release: check out what changed in
173+
[Rust](https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1580-2022-01-13),
174+
[Cargo](https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-158-2022-01-13),
175+
and [Clippy](https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-158).
176+
177+
### Contributors to 1.58.0
178+
179+
Many people came together to create Rust 1.58.0.
180+
We couldn't have done it without all of you.
181+
[Thanks!](https://thanks.rust-lang.org/rust/1.58.0/)

0 commit comments

Comments
 (0)