Skip to content

Commit 3a648bc

Browse files
authored
Merge pull request #391 from Centril/patch-2
First draft of 1.35 announcement
2 parents 0bfbe62 + 6dc0b18 commit 3a648bc

File tree

1 file changed

+290
-0
lines changed

1 file changed

+290
-0
lines changed

posts/2019-05-23-Rust-1.35.0.md

Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
---
2+
layout: post
3+
title: "Announcing Rust 1.35.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.35.0. Rust is a
9+
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.35.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] from the appropriate page on our website,
18+
and check out the [detailed release notes for 1.35.0][notes] on GitHub.
19+
20+
[install]: https://www.rust-lang.org/install.html
21+
[notes]: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1350-2019-05-23
22+
23+
## What's in 1.35.0 stable
24+
25+
The highlight of this release is the implementation of the `FnOnce`, `FnMut`,
26+
and `Fn` closure traits for `Box<dyn FnOnce>`, `Box<dyn FnMut>`, and `Box<dyn Fn>` respectively.
27+
Additionally, closures may now be coerced to unsafe function pointers.
28+
The `dbg!` macro introduced in [Rust 1.32.0] can now also be called without arguments.
29+
Moreover, there were a number of standard library stabilizations.
30+
Read on for a few highlights, or see the [detailed release notes][notes] for additional information.
31+
32+
### `Fn*` closure traits implemented for `Box<dyn Fn*>`
33+
34+
[fn-pr]: https://github.com/rust-lang/rust/pull/55431
35+
[`FnBox`]: https://doc.rust-lang.org/1.34.0/std/boxed/trait.FnBox.html
36+
[unsized locals]: https://doc.rust-lang.org/nightly/unstable-book/language-features/unsized-locals.html
37+
38+
In Rust 1.35.0, the `FnOnce`, `FnMut`, and the `Fn` traits [are now implemented][fn-pr] for `Box<dyn FnOnce>`,
39+
`Box<dyn FnMut>`, and `Box<dyn Fn>` respectively.
40+
41+
Previously, if you wanted to call the function stored in a boxed closure, you had to use [`FnBox`].
42+
This was because instances of `Box<dyn FnOnce>` and friends did not implement the respective `Fn*` traits.
43+
This also meant that it was not possible to pass boxed functions to code expecting an implementor of a `Fn` trait,
44+
and you had to create temporary closures to pass them down.
45+
46+
This was ultimately due to a limitation in the compiler's ability to reason about such implementations,
47+
which has since been fixed with the introduction of [unsized locals].
48+
49+
With this release, you can now use boxed functions in places that expect items implementing a function trait.
50+
51+
The following code now works:
52+
53+
```rust
54+
fn foo(x: Box<dyn Fn(u8) -> u8>) -> Vec<u8> {
55+
vec![1, 2, 3, 4].into_iter().map(x).collect()
56+
}
57+
```
58+
59+
Furthermore, you can now directly call `Box<dyn FnOnce>` objects:
60+
61+
```rust
62+
fn foo(x: Box<dyn FnOnce()>) {
63+
x()
64+
}
65+
```
66+
67+
### Coercing closures to `unsafe fn` pointers
68+
69+
[Rust 1.19.0]: https://blog.rust-lang.org/2017/07/20/Rust-1.19.html
70+
[`RawWakerVTable`]: https://doc.rust-lang.org/beta/std/task/struct.RawWakerVTable.html
71+
72+
Since [Rust 1.19.0], it has been possible to coerce closures that do not capture from their environment into function pointers.
73+
For example, you may write:
74+
75+
```rust
76+
fn twice(x: u8, f: fn(u8) -> u8) -> u8 {
77+
f(f(x))
78+
}
79+
80+
fn main() {
81+
assert_eq!(42, twice(0, |x| x + 21));
82+
}
83+
```
84+
85+
This has however not extended to `unsafe` function pointers.
86+
With this release of Rust, you may now do so. For example:
87+
88+
```rust
89+
/// The safety invariants are those of the `unsafe fn` pointer passed.
90+
unsafe fn call_unsafe_fn_ptr(f: unsafe fn()) {
91+
f()
92+
}
93+
94+
fn main() {
95+
// SAFETY: There are no invariants.
96+
// The closure is statically prevented from doing unsafe things.
97+
unsafe {
98+
call_unsafe_fn_ptr(|| {
99+
dbg!();
100+
});
101+
}
102+
}
103+
```
104+
105+
### Calling `dbg!()` with no argument
106+
107+
[Rust 1.32.0]: https://blog.rust-lang.org/2019/01/17/Rust-1.32.0.html#the-dbg-macro
108+
[the `dbg!` macro]: https://doc.rust-lang.org/std/macro.dbg.html
109+
110+
For the benefit of all the occasional and frequent "print debuggers" out there,
111+
[Rust 1.32.0] saw the release of [the `dbg!` macro].
112+
To recap, the macro allows you to quickly inspect the value of some expression with context.
113+
For example, when running:
114+
115+
```rust
116+
fn main() {
117+
let mut x = 0;
118+
119+
if dbg!(x == 1) {
120+
x += 1;
121+
}
122+
123+
dbg!(x);
124+
}
125+
```
126+
127+
...you would see:
128+
129+
```
130+
[src/main.rs:4] x == 1 = false
131+
[src/main.rs:8] x = 0
132+
```
133+
134+
135+
As seen in the previous section, where the higher order function `call_unsafe_fn_ptr` is called,
136+
you may now also call `dbg!` without passing any arguments.
137+
This is useful when tracing what branches your application takes.
138+
For example, with:
139+
140+
```rust
141+
fn main() {
142+
let condition = true;
143+
144+
if condition {
145+
dbg!();
146+
}
147+
}
148+
```
149+
150+
...you would see:
151+
152+
```
153+
[src/main.rs:5]
154+
```
155+
156+
### Library stabilizations
157+
158+
[`f32::copysign`]: https://doc.rust-lang.org/std/primitive.f32.html#method.copysign
159+
[`f64::copysign`]: https://doc.rust-lang.org/std/primitive.f64.html#method.copysign
160+
[`RefCell::replace_with`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.replace_with
161+
[`Ref::map_split`]: https://doc.rust-lang.org/std/cell/struct.Ref.html#method.map_split
162+
[`RefMut::map_split`]: https://doc.rust-lang.org/std/cell/struct.RefMut.html#method.map_split
163+
[`ptr::hash`]: https://doc.rust-lang.org/std/ptr/fn.hash.html
164+
[`Range::contains`]: https://doc.rust-lang.org/std/ops/struct.Range.html#method.contains
165+
[`RangeFrom::contains`]: https://doc.rust-lang.org/std/ops/struct.RangeFrom.html#method.contains
166+
[`RangeTo::contains`]: https://doc.rust-lang.org/std/ops/struct.RangeTo.html#method.contains
167+
[`RangeInclusive::contains`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html#method.contains
168+
[`RangeToInclusive::contains`]: https://doc.rust-lang.org/std/ops/struct.RangeToInclusive.html#method.contains
169+
[`Option::copied`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.copied
170+
171+
In 1.35.0, a number of APIs have become stable.
172+
173+
In addition, some implementations were added and other changes occured as well.
174+
See the [detailed release notes][notes] for more details.
175+
176+
#### Copy the sign of a floating point number onto another
177+
178+
[`f32`]: https://doc.rust-lang.org/std/primitive.f32.html
179+
[`f64`]: https://doc.rust-lang.org/std/primitive.f64.html
180+
181+
With this release, new methods `copysign` have been added to the floating point primitive types [`f32`] and [`f64`]:
182+
183+
- [`f32::copysign`]
184+
- [`f64::copysign`]
185+
186+
As the name suggests, you can use these to copy the sign of one number onto another. For example:
187+
188+
```rust
189+
fn main() {
190+
assert_eq!(3.5_f32.copysign(-0.42), -3.5);
191+
}
192+
```
193+
194+
#### Check whether a `Range` `contains` a value
195+
196+
Rust 1.35.0 contains a few freshly minted methods on the `Range` types:
197+
198+
- [`Range::contains`]
199+
- [`RangeFrom::contains`]
200+
- [`RangeTo::contains`]
201+
- [`RangeInclusive::contains`]
202+
- [`RangeToInclusive::contains`]
203+
204+
With these, you can easily check whether a given value exists in a range. For example, you may write:
205+
206+
```rust
207+
fn main() {
208+
if (0..=10).contains(&5) {
209+
println!("Five is included in zero to ten.");
210+
}
211+
}
212+
```
213+
214+
#### Map and split a borrowed `RefCell` value in two
215+
216+
With Rust 1.35.0, you can now map and split the borrowed value of a `RefCell` into multiple borrows for different components of the borrowed data:
217+
218+
- [`Ref::map_split`]
219+
- [`RefMut::map_split`]
220+
221+
#### Replace the value of a `RefCell` through a closure
222+
223+
This release introduces a convenience method `replace_with` on `RefCell`:
224+
225+
- [`RefCell::replace_with`]
226+
227+
With it, you can more ergonomically map and replace the current value of the cell and get back the old value as a result.
228+
229+
#### Hash a pointer or reference by address, not value
230+
231+
In this release, we have introduced:
232+
233+
- [`ptr::hash`]
234+
235+
This function takes a raw pointer and hashes it. Using `ptr::hash`,
236+
you can avoid hashing the pointed-to value of a reference and instead hash the address.
237+
238+
#### Copy the contents of an `Option<&T>`
239+
240+
From the very beginning with Rust 1.0.0,
241+
the methods `Option::cloned` for `Option<&T>` and `Option<&mut T>` have allowed you to clone the contents in case of `Some(_)`.
242+
However, cloning can sometimes be an expensive operation and the methods `opt.cloned()` provided no hints to that effect.
243+
244+
With this release of Rust, we introduced:
245+
246+
- [`Option::copied`] for both `Option<&T>` and `Option<&mut T>`
247+
248+
The functionality of `opt.copied()` is the same as for `opt.cloned()`.
249+
However, calling the method requires that `T: Copy`.
250+
Using this method, you can make sure that code stops compiling should `T` no longer implements `Copy`.
251+
252+
### Changes in Clippy
253+
254+
[relnotes-clippy]:
255+
https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-135-beta
256+
257+
[`drop_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_bounds
258+
259+
[split_lint]: https://github.com/rust-lang/rust-clippy/pull/4101
260+
261+
In this release of Rust,
262+
Clippy (a collection of lints to catch common mistakes and improve your Rust code) added a new lint [`drop_bounds`].
263+
This lint triggers when you add a bound `T: Drop` to a generic function. For example:
264+
265+
```rust
266+
fn foo<T: Drop>(x: T) {}
267+
```
268+
269+
Having a bound `T: Drop` is almost always a mistake as it excludes types,
270+
such as `u8`, which have trivial drop-glues.
271+
Moreover, `T: Drop` does not account for types like `String` not having interesting destructor behavior directly but rather as a result of embedding types,
272+
such as `Vec<u8>`, that do.
273+
274+
In addition to [`drop_bounds`],
275+
this release of Clippy [split][split_lint] the lint`redundant_closure` into `redundant_closure` and `redundant_closure_for_method_calls`.
276+
277+
See the [detailed release notes for Clippy][relnotes-clippy] for more details.
278+
279+
### Changes in Cargo
280+
281+
[relnotes-cargo]:
282+
https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-135-2019-05-23
283+
284+
See the [detailed release notes for Cargo][relnotes-cargo] for more details.
285+
286+
## Contributors to 1.35.0
287+
288+
Many people came together to create Rust 1.35.0.
289+
We couldn't have done it without all of you.
290+
[Thanks!](https://thanks.rust-lang.org/rust/1.35.0/)

0 commit comments

Comments
 (0)