Skip to content

Commit c8f5136

Browse files
authored
Rollup merge of rust-lang#129555 - RalfJung:const_float_bits_conv, r=dtolnay
stabilize const_float_bits_conv This stabilizes `const_float_bits_conv`, and thus fixes rust-lang#72447. With rust-lang#128596 having landed, this is entirely a libs-only question now. ```rust impl f32 { pub const fn to_bits(self) -> u32; pub const fn from_bits(v: u32) -> Self; pub const fn to_be_bytes(self) -> [u8; 4]; pub const fn to_le_bytes(self) -> [u8; 4] pub const fn to_ne_bytes(self) -> [u8; 4]; pub const fn from_be_bytes(bytes: [u8; 4]) -> Self; pub const fn from_le_bytes(bytes: [u8; 4]) -> Self; pub const fn from_ne_bytes(bytes: [u8; 4]) -> Self; } impl f64 { pub const fn to_bits(self) -> u64; pub const fn from_bits(v: u64) -> Self; pub const fn to_be_bytes(self) -> [u8; 8]; pub const fn to_le_bytes(self) -> [u8; 8] pub const fn to_ne_bytes(self) -> [u8; 8]; pub const fn from_be_bytes(bytes: [u8; 8]) -> Self; pub const fn from_le_bytes(bytes: [u8; 8]) -> Self; pub const fn from_ne_bytes(bytes: [u8; 8]) -> Self; } ```` Cc `@rust-lang/wg-const-eval` `@rust-lang/libs-api`
2 parents 0b8cb4a + ba2577f commit c8f5136

9 files changed

+186
-46
lines changed

clippy_lints/src/transmute/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -619,10 +619,10 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
619619
| transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context)
620620
| transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg, &self.msrv)
621621
| transmute_int_to_bool::check(cx, e, from_ty, to_ty, arg)
622-
| transmute_int_to_float::check(cx, e, from_ty, to_ty, arg, const_context)
622+
| transmute_int_to_float::check(cx, e, from_ty, to_ty, arg)
623623
| transmute_int_to_non_zero::check(cx, e, from_ty, to_ty, arg)
624-
| transmute_float_to_int::check(cx, e, from_ty, to_ty, arg, const_context)
625-
| transmute_num_to_bytes::check(cx, e, from_ty, to_ty, arg, const_context)
624+
| transmute_float_to_int::check(cx, e, from_ty, to_ty, arg)
625+
| transmute_num_to_bytes::check(cx, e, from_ty, to_ty, arg)
626626
| (unsound_collection_transmute::check(cx, e, from_ty, to_ty)
627627
|| transmute_undefined_repr::check(cx, e, from_ty, to_ty))
628628
| (eager_transmute::check(cx, e, arg, from_ty, to_ty));

clippy_lints/src/transmute/transmute_float_to_int.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@ pub(super) fn check<'tcx>(
1515
from_ty: Ty<'tcx>,
1616
to_ty: Ty<'tcx>,
1717
mut arg: &'tcx Expr<'_>,
18-
const_context: bool,
1918
) -> bool {
2019
match (&from_ty.kind(), &to_ty.kind()) {
21-
(ty::Float(float_ty), ty::Int(_) | ty::Uint(_)) if !const_context => {
20+
(ty::Float(float_ty), ty::Int(_) | ty::Uint(_)) => {
2221
span_lint_and_then(
2322
cx,
2423
TRANSMUTE_FLOAT_TO_INT,

clippy_lints/src/transmute/transmute_int_to_float.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@ pub(super) fn check<'tcx>(
1414
from_ty: Ty<'tcx>,
1515
to_ty: Ty<'tcx>,
1616
arg: &'tcx Expr<'_>,
17-
const_context: bool,
1817
) -> bool {
1918
match (&from_ty.kind(), &to_ty.kind()) {
20-
(ty::Int(_) | ty::Uint(_), ty::Float(_)) if !const_context => {
19+
(ty::Int(_) | ty::Uint(_), ty::Float(_)) => {
2120
span_lint_and_then(
2221
cx,
2322
TRANSMUTE_INT_TO_FLOAT,

clippy_lints/src/transmute/transmute_num_to_bytes.rs

-6
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,12 @@ pub(super) fn check<'tcx>(
1414
from_ty: Ty<'tcx>,
1515
to_ty: Ty<'tcx>,
1616
arg: &'tcx Expr<'_>,
17-
const_context: bool,
1817
) -> bool {
1918
match (&from_ty.kind(), &to_ty.kind()) {
2019
(ty::Int(_) | ty::Uint(_) | ty::Float(_), ty::Array(arr_ty, _)) => {
2120
if !matches!(arr_ty.kind(), ty::Uint(UintTy::U8)) {
2221
return false;
2322
}
24-
if matches!(from_ty.kind(), ty::Float(_)) && const_context {
25-
// TODO: Remove when const_float_bits_conv is stabilized
26-
// rust#72447
27-
return false;
28-
}
2923

3024
span_lint_and_then(
3125
cx,

tests/ui/transmute.rs

+12
Original file line numberDiff line numberDiff line change
@@ -140,24 +140,32 @@ mod int_to_float {
140140

141141
mod issue_5747 {
142142
const VALUE16: f16 = unsafe { std::mem::transmute(0_u16) };
143+
//~^ ERROR: transmute from a `u16` to a `f16`
143144
const VALUE32: f32 = unsafe { std::mem::transmute(0_u32) };
145+
//~^ ERROR: transmute from a `u32` to a `f32`
144146
const VALUE64: f64 = unsafe { std::mem::transmute(0_i64) };
147+
//~^ ERROR: transmute from a `i64` to a `f64`
145148
const VALUE128: f128 = unsafe { std::mem::transmute(0_i128) };
149+
//~^ ERROR: transmute from a `i128` to a `f128`
146150

147151
const fn from_bits_16(v: i16) -> f16 {
148152
unsafe { std::mem::transmute(v) }
153+
//~^ ERROR: transmute from a `i16` to a `f16`
149154
}
150155

151156
const fn from_bits_32(v: i32) -> f32 {
152157
unsafe { std::mem::transmute(v) }
158+
//~^ ERROR: transmute from a `i32` to a `f32`
153159
}
154160

155161
const fn from_bits_64(v: u64) -> f64 {
156162
unsafe { std::mem::transmute(v) }
163+
//~^ ERROR: transmute from a `u64` to a `f64`
157164
}
158165

159166
const fn from_bits_128(v: u128) -> f128 {
160167
unsafe { std::mem::transmute(v) }
168+
//~^ ERROR: transmute from a `u128` to a `f128`
161169
}
162170
}
163171
}
@@ -205,9 +213,13 @@ mod num_to_bytes {
205213
//~^ ERROR: transmute from a `i128` to a `[u8; 16]`
206214

207215
let _: [u8; 2] = std::mem::transmute(0.0f16);
216+
//~^ ERROR: transmute from a `f16` to a `[u8; 2]`
208217
let _: [u8; 4] = std::mem::transmute(0.0f32);
218+
//~^ ERROR: transmute from a `f32` to a `[u8; 4]`
209219
let _: [u8; 8] = std::mem::transmute(0.0f64);
220+
//~^ ERROR: transmute from a `f64` to a `[u8; 8]`
210221
let _: [u8; 16] = std::mem::transmute(0.0f128);
222+
//~^ ERROR: transmute from a `f128` to a `[u8; 16]`
211223
}
212224
}
213225
}

tests/ui/transmute.stderr

+92-20
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,56 @@ error: transmute from a `i128` to a `f128`
148148
LL | let _: f128 = unsafe { std::mem::transmute(0_i128) };
149149
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)`
150150

151+
error: transmute from a `u16` to a `f16`
152+
--> tests/ui/transmute.rs:142:39
153+
|
154+
LL | const VALUE16: f16 = unsafe { std::mem::transmute(0_u16) };
155+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_u16)`
156+
157+
error: transmute from a `u32` to a `f32`
158+
--> tests/ui/transmute.rs:144:39
159+
|
160+
LL | const VALUE32: f32 = unsafe { std::mem::transmute(0_u32) };
161+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)`
162+
163+
error: transmute from a `i64` to a `f64`
164+
--> tests/ui/transmute.rs:146:39
165+
|
166+
LL | const VALUE64: f64 = unsafe { std::mem::transmute(0_i64) };
167+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)`
168+
169+
error: transmute from a `i128` to a `f128`
170+
--> tests/ui/transmute.rs:148:41
171+
|
172+
LL | const VALUE128: f128 = unsafe { std::mem::transmute(0_i128) };
173+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)`
174+
175+
error: transmute from a `i16` to a `f16`
176+
--> tests/ui/transmute.rs:152:22
177+
|
178+
LL | unsafe { std::mem::transmute(v) }
179+
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(v as u16)`
180+
181+
error: transmute from a `i32` to a `f32`
182+
--> tests/ui/transmute.rs:157:22
183+
|
184+
LL | unsafe { std::mem::transmute(v) }
185+
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(v as u32)`
186+
187+
error: transmute from a `u64` to a `f64`
188+
--> tests/ui/transmute.rs:162:22
189+
|
190+
LL | unsafe { std::mem::transmute(v) }
191+
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(v)`
192+
193+
error: transmute from a `u128` to a `f128`
194+
--> tests/ui/transmute.rs:167:22
195+
|
196+
LL | unsafe { std::mem::transmute(v) }
197+
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(v)`
198+
151199
error: transmute from a `u8` to a `[u8; 1]`
152-
--> tests/ui/transmute.rs:168:30
200+
--> tests/ui/transmute.rs:176:30
153201
|
154202
LL | let _: [u8; 1] = std::mem::transmute(0u8);
155203
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
@@ -158,97 +206,121 @@ LL | let _: [u8; 1] = std::mem::transmute(0u8);
158206
= help: to override `-D warnings` add `#[allow(clippy::transmute_num_to_bytes)]`
159207

160208
error: transmute from a `u32` to a `[u8; 4]`
161-
--> tests/ui/transmute.rs:171:30
209+
--> tests/ui/transmute.rs:179:30
162210
|
163211
LL | let _: [u8; 4] = std::mem::transmute(0u32);
164212
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
165213

166214
error: transmute from a `u128` to a `[u8; 16]`
167-
--> tests/ui/transmute.rs:173:31
215+
--> tests/ui/transmute.rs:181:31
168216
|
169217
LL | let _: [u8; 16] = std::mem::transmute(0u128);
170218
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
171219

172220
error: transmute from a `i8` to a `[u8; 1]`
173-
--> tests/ui/transmute.rs:175:30
221+
--> tests/ui/transmute.rs:183:30
174222
|
175223
LL | let _: [u8; 1] = std::mem::transmute(0i8);
176224
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
177225

178226
error: transmute from a `i32` to a `[u8; 4]`
179-
--> tests/ui/transmute.rs:177:30
227+
--> tests/ui/transmute.rs:185:30
180228
|
181229
LL | let _: [u8; 4] = std::mem::transmute(0i32);
182230
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
183231

184232
error: transmute from a `i128` to a `[u8; 16]`
185-
--> tests/ui/transmute.rs:179:31
233+
--> tests/ui/transmute.rs:187:31
186234
|
187235
LL | let _: [u8; 16] = std::mem::transmute(0i128);
188236
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
189237

190238
error: transmute from a `f16` to a `[u8; 2]`
191-
--> tests/ui/transmute.rs:182:30
239+
--> tests/ui/transmute.rs:190:30
192240
|
193241
LL | let _: [u8; 2] = std::mem::transmute(0.0f16);
194242
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()`
195243

196244
error: transmute from a `f32` to a `[u8; 4]`
197-
--> tests/ui/transmute.rs:184:30
245+
--> tests/ui/transmute.rs:192:30
198246
|
199247
LL | let _: [u8; 4] = std::mem::transmute(0.0f32);
200248
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()`
201249

202250
error: transmute from a `f64` to a `[u8; 8]`
203-
--> tests/ui/transmute.rs:186:30
251+
--> tests/ui/transmute.rs:194:30
204252
|
205253
LL | let _: [u8; 8] = std::mem::transmute(0.0f64);
206254
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()`
207255

208256
error: transmute from a `f128` to a `[u8; 16]`
209-
--> tests/ui/transmute.rs:188:31
257+
--> tests/ui/transmute.rs:196:31
210258
|
211259
LL | let _: [u8; 16] = std::mem::transmute(0.0f128);
212260
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()`
213261

214262
error: transmute from a `u8` to a `[u8; 1]`
215-
--> tests/ui/transmute.rs:194:30
263+
--> tests/ui/transmute.rs:202:30
216264
|
217265
LL | let _: [u8; 1] = std::mem::transmute(0u8);
218266
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
219267

220268
error: transmute from a `u32` to a `[u8; 4]`
221-
--> tests/ui/transmute.rs:196:30
269+
--> tests/ui/transmute.rs:204:30
222270
|
223271
LL | let _: [u8; 4] = std::mem::transmute(0u32);
224272
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
225273

226274
error: transmute from a `u128` to a `[u8; 16]`
227-
--> tests/ui/transmute.rs:198:31
275+
--> tests/ui/transmute.rs:206:31
228276
|
229277
LL | let _: [u8; 16] = std::mem::transmute(0u128);
230278
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
231279

232280
error: transmute from a `i8` to a `[u8; 1]`
233-
--> tests/ui/transmute.rs:200:30
281+
--> tests/ui/transmute.rs:208:30
234282
|
235283
LL | let _: [u8; 1] = std::mem::transmute(0i8);
236284
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
237285

238286
error: transmute from a `i32` to a `[u8; 4]`
239-
--> tests/ui/transmute.rs:202:30
287+
--> tests/ui/transmute.rs:210:30
240288
|
241289
LL | let _: [u8; 4] = std::mem::transmute(0i32);
242290
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
243291

244292
error: transmute from a `i128` to a `[u8; 16]`
245-
--> tests/ui/transmute.rs:204:31
293+
--> tests/ui/transmute.rs:212:31
246294
|
247295
LL | let _: [u8; 16] = std::mem::transmute(0i128);
248296
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
249297

298+
error: transmute from a `f16` to a `[u8; 2]`
299+
--> tests/ui/transmute.rs:215:30
300+
|
301+
LL | let _: [u8; 2] = std::mem::transmute(0.0f16);
302+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()`
303+
304+
error: transmute from a `f32` to a `[u8; 4]`
305+
--> tests/ui/transmute.rs:217:30
306+
|
307+
LL | let _: [u8; 4] = std::mem::transmute(0.0f32);
308+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()`
309+
310+
error: transmute from a `f64` to a `[u8; 8]`
311+
--> tests/ui/transmute.rs:219:30
312+
|
313+
LL | let _: [u8; 8] = std::mem::transmute(0.0f64);
314+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()`
315+
316+
error: transmute from a `f128` to a `[u8; 16]`
317+
--> tests/ui/transmute.rs:221:31
318+
|
319+
LL | let _: [u8; 16] = std::mem::transmute(0.0f128);
320+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()`
321+
250322
error: transmute from a `&[u8]` to a `&str`
251-
--> tests/ui/transmute.rs:218:28
323+
--> tests/ui/transmute.rs:230:28
252324
|
253325
LL | let _: &str = unsafe { std::mem::transmute(B) };
254326
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()`
@@ -257,16 +329,16 @@ LL | let _: &str = unsafe { std::mem::transmute(B) };
257329
= help: to override `-D warnings` add `#[allow(clippy::transmute_bytes_to_str)]`
258330

259331
error: transmute from a `&mut [u8]` to a `&mut str`
260-
--> tests/ui/transmute.rs:221:32
332+
--> tests/ui/transmute.rs:233:32
261333
|
262334
LL | let _: &mut str = unsafe { std::mem::transmute(mb) };
263335
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`
264336

265337
error: transmute from a `&[u8]` to a `&str`
266-
--> tests/ui/transmute.rs:223:30
338+
--> tests/ui/transmute.rs:235:30
267339
|
268340
LL | const _: &str = unsafe { std::mem::transmute(B) };
269341
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)`
270342

271-
error: aborting due to 42 previous errors
343+
error: aborting due to 54 previous errors
272344

tests/ui/transmute_float_to_int.fixed

+18-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![warn(clippy::transmute_float_to_int)]
22
#![allow(clippy::missing_transmute_annotations)]
3-
#![feature(f128)]
4-
#![feature(f16)]
3+
#![feature(f128, f128_const)]
4+
#![feature(f16, f16_const)]
55

66
fn float_to_int() {
77
let _: u32 = unsafe { 1f32.to_bits() };
@@ -20,25 +20,33 @@ fn float_to_int() {
2020
}
2121

2222
mod issue_5747 {
23-
const VALUE16: i16 = unsafe { std::mem::transmute(1f16) };
24-
const VALUE32: i32 = unsafe { std::mem::transmute(1f32) };
25-
const VALUE64: u64 = unsafe { std::mem::transmute(1f64) };
26-
const VALUE128: u128 = unsafe { std::mem::transmute(1f128) };
23+
const VALUE16: i16 = unsafe { 1f16.to_bits() as i16 };
24+
//~^ ERROR: transmute from a `f16` to a `i16`
25+
const VALUE32: i32 = unsafe { 1f32.to_bits() as i32 };
26+
//~^ ERROR: transmute from a `f32` to a `i32`
27+
const VALUE64: u64 = unsafe { 1f64.to_bits() };
28+
//~^ ERROR: transmute from a `f64` to a `u64`
29+
const VALUE128: u128 = unsafe { 1f128.to_bits() };
30+
//~^ ERROR: transmute from a `f128` to a `u128`
2731

2832
const fn to_bits_16(v: f16) -> u16 {
29-
unsafe { std::mem::transmute(v) }
33+
unsafe { v.to_bits() }
34+
//~^ ERROR: transmute from a `f16` to a `u16`
3035
}
3136

3237
const fn to_bits_32(v: f32) -> u32 {
33-
unsafe { std::mem::transmute(v) }
38+
unsafe { v.to_bits() }
39+
//~^ ERROR: transmute from a `f32` to a `u32`
3440
}
3541

3642
const fn to_bits_64(v: f64) -> i64 {
37-
unsafe { std::mem::transmute(v) }
43+
unsafe { v.to_bits() as i64 }
44+
//~^ ERROR: transmute from a `f64` to a `i64`
3845
}
3946

4047
const fn to_bits_128(v: f128) -> i128 {
41-
unsafe { std::mem::transmute(v) }
48+
unsafe { v.to_bits() as i128 }
49+
//~^ ERROR: transmute from a `f128` to a `i128`
4250
}
4351
}
4452

0 commit comments

Comments
 (0)