You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: posts/2024-10-17-Rust-1.82.0.md
+65-65Lines changed: 65 additions & 65 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -57,42 +57,6 @@ The Rust target `aarch64-apple-darwin` for macOS on 64-bit ARM (M1-family or lat
57
57
58
58
[The targets](https://doc.rust-lang.org/nightly/rustc/platform-support/apple-ios-macabi.html) are now tier 2, and can be downloaded with `rustup target add aarch64-apple-ios-macabi x86_64-apple-ios-macabi`, so now is an excellent time to update your CI pipeline to test that your code also runs in iOS-like environments.
59
59
60
-
### Omitting empty types in pattern matching
61
-
62
-
Patterns which match empty (a.k.a. uninhabited) types by value can now be omitted:
letOk(x) =x; // the `Err` case does not need to appear
68
-
x
69
-
}
70
-
```
71
-
72
-
This works with empty types such as a variant-less `enum Void {}`, or structs and enums with a visible empty field and no `#[non_exhaustive]` attribute. It will also be particularly useful in combination with the never type `!`, although that type is still unstable at this time.
73
-
74
-
There are still some cases where empty patterns must still be written. For reasons related to uninitialized values and unsafe code, omitting patterns is not allowed if the empty type is accessed through a reference, pointer, or union field:
// this arm cannot be omitted because of the reference
81
-
Err(infallible) =>match*infallible {},
82
-
}
83
-
}
84
-
```
85
-
86
-
To avoid interfering with crates that wish to support several Rust versions, `match` arms with empty patterns are not yet reported as “unreachable code” warnings, despite the fact that they can be removed.
87
-
88
-
### Floating-point NaN semantics and `const`
89
-
90
-
Operations on floating-point values (of type `f32` and `f64`) are famously subtle. One of the reasons for this is the existence of "NaN values": this is short for "not a number", and is used to represent e.g. the result of `0.0 / 0.0`. What makes NaN values subtle is that more than one possible NaN value exists: a NaN value has a sign that can be checked with `f.is_sign_positive()`, and it has a "payload" that can be extracted with `f.to_bits()`. Despite very successful efforts to standardize the behavior of floating-point operations across hardware architectures, the details of when a NaN is positive or negative and what its exact payload is differ across architectures. To make matters even more complicated, Rust and its LLVM backend apply optimizations to floating-point operations when the exact numeric result is guaranteed not to change, but those optimizations can change which NaN value is produced. For instance, `f * 1.0` may be optimized to just `f`. However, if `f` is a NaN, this can change the exact bit pattern of the result!
91
-
92
-
With this release, Rust standardizes on a set of rules for how NaN values behave. This set of rules is *not* fully deterministic, which means that the result of operations like `(0.0 / 0.0).is_sign_positive()` can differ depending on the hardware architecture, optimization levels, and the surrounding code. Code that aims to be fully portable should avoid using `to_bits` and should use `f.signum() == 1.0` instead of `f.is_sign_positive()`. However, the rules are carefully chosen to still allow advanced data representation techniques such as NaN boxing to be implemented in Rust code. For more details on what the exact rules are, check out our [documentation](https://doc.rust-lang.org/std/primitive.f32.html#nan-bit-patterns).
93
-
94
-
With the semantics for NaN values settled, this release also permits the use of floating-point operations in `const fn`. Due to the reasons described above, operations like `(0.0 / 0.0).is_sign_positive()` can produce a different result when executed at compile-time vs at run-time; this is not a bug and code must not rely on a `const fn` always producing the exact same result.
95
-
96
60
### Native syntax for creating a raw pointer
97
61
98
62
Unsafe code sometimes has to deal with pointers that may dangle, may be misaligned, or may not point to valid data. A common case where this comes up are `repr(packed)` structs. In such a case, it is important to avoid creating a reference, as that would cause undefined behavior. This means the usual `&` and `&mut` operators cannot be used, as those create a reference -- even if the reference is immediately cast to a raw pointer, it's too late to avoid the undefined behavior.
@@ -127,35 +91,6 @@ fn main() {
127
91
128
92
The native syntax makes it more clear that the operand expression of these operators is interpreted as a [place expression](https://www.ralfj.de/blog/2024/08/14/places.html). It also avoids the term "address-of" when referring to the action of creating a pointer. A pointer is [more than just an address](https://rust-lang.github.io/rfcs/3559-rust-has-provenance.html), so Rust is moving away from terms like "address-of" that reaffirm a false equivalence of pointers and addresses.
129
93
130
-
### Safely addressing unsafe `static`s
131
-
132
-
This code is now allowed:
133
-
134
-
```rust
135
-
staticmutSTATIC_MUT:Type=Type::new();
136
-
extern"C" {
137
-
staticEXTERN_STATIC:Type;
138
-
}
139
-
fnmain() {
140
-
letstatic_mut_ptr=&rawmutSTATIC_MUT;
141
-
letextern_static_ptr=&rawconstEXTERN_STATIC;
142
-
}
143
-
```
144
-
145
-
In an expression context, `STATIC_MUT` and `EXTERN_STATIC` are [place expressions](https://doc.rust-lang.org/reference/expressions.html#place-expressions-and-value-expressions). Previously, the compiler's safety checks were not aware that the raw ref operator did not actually affect the operand's place, treating it as a possible read or write to a pointer. No unsafety is actually present, however, as it just creates a pointer.
146
-
147
-
Relaxing this may cause problems where some unsafe blocks are now reported as unused if you deny the `unused_unsafe` lint, but they are now only useful on older versions. Annotate these unsafe blocks with `#[allow(unused_unsafe)]` if you wish to support multiple versions of Rust, as in this example diff:
148
-
149
-
```diff
150
-
static mut STATIC_MUT: Type = Type::new();
151
-
fn main() {
152
-
+ #[allow(unused_unsafe)]
153
-
let static_mut_ptr = unsafe { std::ptr::addr_of_mut!(STATIC_MUT) };
154
-
}
155
-
```
156
-
157
-
A future version of Rust is expected to generalize this to other expressions which would be safe in this position, not just statics.
158
-
159
94
### Safe items in `unsafe extern`
160
95
161
96
Rust code can use functions and statics from foreign code. The type signatures of these foreign items are provided in `extern` blocks. Historically, all items within `extern` blocks have been unsafe to call, but we didn't have to write `unsafe` anywhere on the `extern` block itself.
@@ -195,6 +130,42 @@ This affects the following attributes:
195
130
196
131
For further details, see the ["Unsafe attributes"](https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-attributes.html) chapter of the edition guide.
197
132
133
+
### Omitting empty types in pattern matching
134
+
135
+
Patterns which match empty (a.k.a. uninhabited) types by value can now be omitted:
letOk(x) =x; // the `Err` case does not need to appear
141
+
x
142
+
}
143
+
```
144
+
145
+
This works with empty types such as a variant-less `enum Void {}`, or structs and enums with a visible empty field and no `#[non_exhaustive]` attribute. It will also be particularly useful in combination with the never type `!`, although that type is still unstable at this time.
146
+
147
+
There are still some cases where empty patterns must still be written. For reasons related to uninitialized values and unsafe code, omitting patterns is not allowed if the empty type is accessed through a reference, pointer, or union field:
// this arm cannot be omitted because of the reference
154
+
Err(infallible) =>match*infallible {},
155
+
}
156
+
}
157
+
```
158
+
159
+
To avoid interfering with crates that wish to support several Rust versions, `match` arms with empty patterns are not yet reported as “unreachable code” warnings, despite the fact that they can be removed.
160
+
161
+
### Floating-point NaN semantics and `const`
162
+
163
+
Operations on floating-point values (of type `f32` and `f64`) are famously subtle. One of the reasons for this is the existence of "NaN values": this is short for "not a number", and is used to represent e.g. the result of `0.0 / 0.0`. What makes NaN values subtle is that more than one possible NaN value exists: a NaN value has a sign that can be checked with `f.is_sign_positive()`, and it has a "payload" that can be extracted with `f.to_bits()`. Despite very successful efforts to standardize the behavior of floating-point operations across hardware architectures, the details of when a NaN is positive or negative and what its exact payload is differ across architectures. To make matters even more complicated, Rust and its LLVM backend apply optimizations to floating-point operations when the exact numeric result is guaranteed not to change, but those optimizations can change which NaN value is produced. For instance, `f * 1.0` may be optimized to just `f`. However, if `f` is a NaN, this can change the exact bit pattern of the result!
164
+
165
+
With this release, Rust standardizes on a set of rules for how NaN values behave. This set of rules is *not* fully deterministic, which means that the result of operations like `(0.0 / 0.0).is_sign_positive()` can differ depending on the hardware architecture, optimization levels, and the surrounding code. Code that aims to be fully portable should avoid using `to_bits` and should use `f.signum() == 1.0` instead of `f.is_sign_positive()`. However, the rules are carefully chosen to still allow advanced data representation techniques such as NaN boxing to be implemented in Rust code. For more details on what the exact rules are, check out our [documentation](https://doc.rust-lang.org/std/primitive.f32.html#nan-bit-patterns).
166
+
167
+
With the semantics for NaN values settled, this release also permits the use of floating-point operations in `const fn`. Due to the reasons described above, operations like `(0.0 / 0.0).is_sign_positive()` can produce a different result when executed at compile-time vs at run-time; this is not a bug and code must not rely on a `const fn` always producing the exact same result.
168
+
198
169
### Constants as assembly immediates
199
170
200
171
The `const` assembly operand now provides a way to use integers as immediates
@@ -251,6 +222,35 @@ mov rax, rax # save the return value
251
222
See [the reference](https://doc.rust-lang.org/reference/inline-assembly.html)
252
223
for more details.
253
224
225
+
### Safely addressing unsafe `static`s
226
+
227
+
This code is now allowed:
228
+
229
+
```rust
230
+
staticmutSTATIC_MUT:Type=Type::new();
231
+
extern"C" {
232
+
staticEXTERN_STATIC:Type;
233
+
}
234
+
fnmain() {
235
+
letstatic_mut_ptr=&rawmutSTATIC_MUT;
236
+
letextern_static_ptr=&rawconstEXTERN_STATIC;
237
+
}
238
+
```
239
+
240
+
In an expression context, `STATIC_MUT` and `EXTERN_STATIC` are [place expressions](https://doc.rust-lang.org/reference/expressions.html#place-expressions-and-value-expressions). Previously, the compiler's safety checks were not aware that the raw ref operator did not actually affect the operand's place, treating it as a possible read or write to a pointer. No unsafety is actually present, however, as it just creates a pointer.
241
+
242
+
Relaxing this may cause problems where some unsafe blocks are now reported as unused if you deny the `unused_unsafe` lint, but they are now only useful on older versions. Annotate these unsafe blocks with `#[allow(unused_unsafe)]` if you wish to support multiple versions of Rust, as in this example diff:
243
+
244
+
```diff
245
+
static mut STATIC_MUT: Type = Type::new();
246
+
fn main() {
247
+
+ #[allow(unused_unsafe)]
248
+
let static_mut_ptr = unsafe { std::ptr::addr_of_mut!(STATIC_MUT) };
249
+
}
250
+
```
251
+
252
+
A future version of Rust is expected to generalize this to other expressions which would be safe in this position, not just statics.
0 commit comments