Skip to content

Commit d891954

Browse files
committed
Auto merge of #5919 - ebroto:5747_from_bits_in_const, r=matthiaskrgr
transmute: avoid suggesting from/to bits in const changelog: Avoid suggesting from/to bits in const contexts in [`transmute_int_to_float`] Fixes #5747
2 parents 6220dff + 6a12bae commit d891954

File tree

5 files changed

+88
-40
lines changed

5 files changed

+88
-40
lines changed

clippy_lints/src/transmute.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::utils::{
2-
is_normalizable, last_path_segment, match_def_path, paths, snippet, span_lint, span_lint_and_sugg,
2+
in_constant, is_normalizable, last_path_segment, match_def_path, paths, snippet, span_lint, span_lint_and_sugg,
33
span_lint_and_then, sugg,
44
};
55
use if_chain::if_chain;
@@ -331,6 +331,10 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
331331
if let Some(def_id) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id();
332332
if match_def_path(cx, def_id, &paths::TRANSMUTE);
333333
then {
334+
// Avoid suggesting from/to bits in const contexts.
335+
// See https://github.com/rust-lang/rust/issues/73736 for progress on making them `const fn`.
336+
let const_context = in_constant(cx, e.hir_id);
337+
334338
let from_ty = cx.typeck_results().expr_ty(&args[0]);
335339
let to_ty = cx.typeck_results().expr_ty(e);
336340

@@ -544,7 +548,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
544548
},
545549
)
546550
},
547-
(ty::Int(_) | ty::Uint(_), ty::Float(_)) => span_lint_and_then(
551+
(ty::Int(_) | ty::Uint(_), ty::Float(_)) if !const_context => span_lint_and_then(
548552
cx,
549553
TRANSMUTE_INT_TO_FLOAT,
550554
e.span,
@@ -567,7 +571,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
567571
);
568572
},
569573
),
570-
(ty::Float(float_ty), ty::Int(_) | ty::Uint(_)) => span_lint_and_then(
574+
(ty::Float(float_ty), ty::Int(_) | ty::Uint(_)) if !const_context => span_lint_and_then(
571575
cx,
572576
TRANSMUTE_FLOAT_TO_INT,
573577
e.span,

tests/ui/transmute.rs

+21-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![feature(const_fn_transmute)]
12
#![allow(dead_code)]
23

34
extern crate core;
@@ -81,9 +82,26 @@ fn int_to_bool() {
8182
}
8283

8384
#[warn(clippy::transmute_int_to_float)]
84-
fn int_to_float() {
85-
let _: f32 = unsafe { std::mem::transmute(0_u32) };
86-
let _: f32 = unsafe { std::mem::transmute(0_i32) };
85+
mod int_to_float {
86+
fn test() {
87+
let _: f32 = unsafe { std::mem::transmute(0_u32) };
88+
let _: f32 = unsafe { std::mem::transmute(0_i32) };
89+
let _: f64 = unsafe { std::mem::transmute(0_u64) };
90+
let _: f64 = unsafe { std::mem::transmute(0_i64) };
91+
}
92+
93+
mod issue_5747 {
94+
const VALUE32: f32 = unsafe { std::mem::transmute(0_u32) };
95+
const VALUE64: f64 = unsafe { std::mem::transmute(0_i64) };
96+
97+
const fn from_bits_32(v: i32) -> f32 {
98+
unsafe { std::mem::transmute(v) }
99+
}
100+
101+
const fn from_bits_64(v: u64) -> f64 {
102+
unsafe { std::mem::transmute(v) }
103+
}
104+
}
87105
}
88106

89107
fn bytes_to_str(b: &[u8], mb: &mut [u8]) {

tests/ui/transmute.stderr

+39-27
Original file line numberDiff line numberDiff line change
@@ -1,146 +1,158 @@
11
error: transmute from a type (`&T`) to itself
2-
--> $DIR/transmute.rs:19:20
2+
--> $DIR/transmute.rs:20:20
33
|
44
LL | let _: &'a T = core::intrinsics::transmute(t);
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
= note: `-D clippy::useless-transmute` implied by `-D warnings`
88

99
error: transmute from a reference to a pointer
10-
--> $DIR/transmute.rs:23:23
10+
--> $DIR/transmute.rs:24:23
1111
|
1212
LL | let _: *const T = core::intrinsics::transmute(t);
1313
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T`
1414

1515
error: transmute from a reference to a pointer
16-
--> $DIR/transmute.rs:25:21
16+
--> $DIR/transmute.rs:26:21
1717
|
1818
LL | let _: *mut T = core::intrinsics::transmute(t);
1919
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *mut T`
2020

2121
error: transmute from a reference to a pointer
22-
--> $DIR/transmute.rs:27:23
22+
--> $DIR/transmute.rs:28:23
2323
|
2424
LL | let _: *const U = core::intrinsics::transmute(t);
2525
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *const U`
2626

2727
error: transmute from a type (`std::vec::Vec<i32>`) to itself
28-
--> $DIR/transmute.rs:33:27
28+
--> $DIR/transmute.rs:34:27
2929
|
3030
LL | let _: Vec<i32> = core::intrinsics::transmute(my_vec());
3131
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3232

3333
error: transmute from a type (`std::vec::Vec<i32>`) to itself
34-
--> $DIR/transmute.rs:35:27
34+
--> $DIR/transmute.rs:36:27
3535
|
3636
LL | let _: Vec<i32> = core::mem::transmute(my_vec());
3737
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3838

3939
error: transmute from a type (`std::vec::Vec<i32>`) to itself
40-
--> $DIR/transmute.rs:37:27
40+
--> $DIR/transmute.rs:38:27
4141
|
4242
LL | let _: Vec<i32> = std::intrinsics::transmute(my_vec());
4343
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4444

4545
error: transmute from a type (`std::vec::Vec<i32>`) to itself
46-
--> $DIR/transmute.rs:39:27
46+
--> $DIR/transmute.rs:40:27
4747
|
4848
LL | let _: Vec<i32> = std::mem::transmute(my_vec());
4949
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5050

5151
error: transmute from a type (`std::vec::Vec<i32>`) to itself
52-
--> $DIR/transmute.rs:41:27
52+
--> $DIR/transmute.rs:42:27
5353
|
5454
LL | let _: Vec<i32> = my_transmute(my_vec());
5555
| ^^^^^^^^^^^^^^^^^^^^^^
5656

5757
error: transmute from an integer to a pointer
58-
--> $DIR/transmute.rs:43:31
58+
--> $DIR/transmute.rs:44:31
5959
|
6060
LL | let _: *const usize = std::mem::transmute(5_isize);
6161
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `5_isize as *const usize`
6262

6363
error: transmute from an integer to a pointer
64-
--> $DIR/transmute.rs:47:31
64+
--> $DIR/transmute.rs:48:31
6565
|
6666
LL | let _: *const usize = std::mem::transmute(1 + 1usize);
6767
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(1 + 1usize) as *const usize`
6868

6969
error: transmute from a type (`*const Usize`) to the type that it points to (`Usize`)
70-
--> $DIR/transmute.rs:62:24
70+
--> $DIR/transmute.rs:63:24
7171
|
7272
LL | let _: Usize = core::intrinsics::transmute(int_const_ptr);
7373
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7474
|
7575
= note: `-D clippy::crosspointer-transmute` implied by `-D warnings`
7676

7777
error: transmute from a type (`*mut Usize`) to the type that it points to (`Usize`)
78-
--> $DIR/transmute.rs:64:24
78+
--> $DIR/transmute.rs:65:24
7979
|
8080
LL | let _: Usize = core::intrinsics::transmute(int_mut_ptr);
8181
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8282

8383
error: transmute from a type (`Usize`) to a pointer to that type (`*const Usize`)
84-
--> $DIR/transmute.rs:66:31
84+
--> $DIR/transmute.rs:67:31
8585
|
8686
LL | let _: *const Usize = core::intrinsics::transmute(my_int());
8787
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8888

8989
error: transmute from a type (`Usize`) to a pointer to that type (`*mut Usize`)
90-
--> $DIR/transmute.rs:68:29
90+
--> $DIR/transmute.rs:69:29
9191
|
9292
LL | let _: *mut Usize = core::intrinsics::transmute(my_int());
9393
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9494

9595
error: transmute from a `u32` to a `char`
96-
--> $DIR/transmute.rs:74:28
96+
--> $DIR/transmute.rs:75:28
9797
|
9898
LL | let _: char = unsafe { std::mem::transmute(0_u32) };
9999
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_u32).unwrap()`
100100
|
101101
= note: `-D clippy::transmute-int-to-char` implied by `-D warnings`
102102

103103
error: transmute from a `i32` to a `char`
104-
--> $DIR/transmute.rs:75:28
104+
--> $DIR/transmute.rs:76:28
105105
|
106106
LL | let _: char = unsafe { std::mem::transmute(0_i32) };
107107
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_i32 as u32).unwrap()`
108108

109109
error: transmute from a `u8` to a `bool`
110-
--> $DIR/transmute.rs:80:28
110+
--> $DIR/transmute.rs:81:28
111111
|
112112
LL | let _: bool = unsafe { std::mem::transmute(0_u8) };
113113
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `0_u8 != 0`
114114
|
115115
= note: `-D clippy::transmute-int-to-bool` implied by `-D warnings`
116116

117117
error: transmute from a `u32` to a `f32`
118-
--> $DIR/transmute.rs:85:27
118+
--> $DIR/transmute.rs:87:31
119119
|
120-
LL | let _: f32 = unsafe { std::mem::transmute(0_u32) };
121-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)`
120+
LL | let _: f32 = unsafe { std::mem::transmute(0_u32) };
121+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)`
122122
|
123123
= note: `-D clippy::transmute-int-to-float` implied by `-D warnings`
124124

125125
error: transmute from a `i32` to a `f32`
126-
--> $DIR/transmute.rs:86:27
126+
--> $DIR/transmute.rs:88:31
127+
|
128+
LL | let _: f32 = unsafe { std::mem::transmute(0_i32) };
129+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)`
130+
131+
error: transmute from a `u64` to a `f64`
132+
--> $DIR/transmute.rs:89:31
133+
|
134+
LL | let _: f64 = unsafe { std::mem::transmute(0_u64) };
135+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_u64)`
136+
137+
error: transmute from a `i64` to a `f64`
138+
--> $DIR/transmute.rs:90:31
127139
|
128-
LL | let _: f32 = unsafe { std::mem::transmute(0_i32) };
129-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)`
140+
LL | let _: f64 = unsafe { std::mem::transmute(0_i64) };
141+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)`
130142

131143
error: transmute from a `&[u8]` to a `&str`
132-
--> $DIR/transmute.rs:90:28
144+
--> $DIR/transmute.rs:108:28
133145
|
134146
LL | let _: &str = unsafe { std::mem::transmute(b) };
135147
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(b).unwrap()`
136148
|
137149
= note: `-D clippy::transmute-bytes-to-str` implied by `-D warnings`
138150

139151
error: transmute from a `&mut [u8]` to a `&mut str`
140-
--> $DIR/transmute.rs:91:32
152+
--> $DIR/transmute.rs:109:32
141153
|
142154
LL | let _: &mut str = unsafe { std::mem::transmute(mb) };
143155
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`
144156

145-
error: aborting due to 22 previous errors
157+
error: aborting due to 24 previous errors
146158

tests/ui/transmute_float_to_int.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
#[warn(clippy::transmute_float_to_int)]
1+
#![feature(const_fn_transmute)]
2+
#![warn(clippy::transmute_float_to_int)]
23

34
fn float_to_int() {
45
let _: u32 = unsafe { std::mem::transmute(1f32) };
@@ -9,4 +10,17 @@ fn float_to_int() {
910
let _: u64 = unsafe { std::mem::transmute(-1.0) };
1011
}
1112

13+
mod issue_5747 {
14+
const VALUE32: i32 = unsafe { std::mem::transmute(1f32) };
15+
const VALUE64: u64 = unsafe { std::mem::transmute(1f64) };
16+
17+
const fn to_bits_32(v: f32) -> u32 {
18+
unsafe { std::mem::transmute(v) }
19+
}
20+
21+
const fn to_bits_64(v: f64) -> i64 {
22+
unsafe { std::mem::transmute(v) }
23+
}
24+
}
25+
1226
fn main() {}

tests/ui/transmute_float_to_int.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,37 @@
11
error: transmute from a `f32` to a `u32`
2-
--> $DIR/transmute_float_to_int.rs:4:27
2+
--> $DIR/transmute_float_to_int.rs:5:27
33
|
44
LL | let _: u32 = unsafe { std::mem::transmute(1f32) };
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f32.to_bits()`
66
|
77
= note: `-D clippy::transmute-float-to-int` implied by `-D warnings`
88

99
error: transmute from a `f32` to a `i32`
10-
--> $DIR/transmute_float_to_int.rs:5:27
10+
--> $DIR/transmute_float_to_int.rs:6:27
1111
|
1212
LL | let _: i32 = unsafe { std::mem::transmute(1f32) };
1313
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f32.to_bits() as i32`
1414

1515
error: transmute from a `f64` to a `u64`
16-
--> $DIR/transmute_float_to_int.rs:6:27
16+
--> $DIR/transmute_float_to_int.rs:7:27
1717
|
1818
LL | let _: u64 = unsafe { std::mem::transmute(1f64) };
1919
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits()`
2020

2121
error: transmute from a `f64` to a `i64`
22-
--> $DIR/transmute_float_to_int.rs:7:27
22+
--> $DIR/transmute_float_to_int.rs:8:27
2323
|
2424
LL | let _: i64 = unsafe { std::mem::transmute(1f64) };
2525
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits() as i64`
2626

2727
error: transmute from a `f64` to a `u64`
28-
--> $DIR/transmute_float_to_int.rs:8:27
28+
--> $DIR/transmute_float_to_int.rs:9:27
2929
|
3030
LL | let _: u64 = unsafe { std::mem::transmute(1.0) };
3131
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.0f64.to_bits()`
3232

3333
error: transmute from a `f64` to a `u64`
34-
--> $DIR/transmute_float_to_int.rs:9:27
34+
--> $DIR/transmute_float_to_int.rs:10:27
3535
|
3636
LL | let _: u64 = unsafe { std::mem::transmute(-1.0) };
3737
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-1.0f64).to_bits()`

0 commit comments

Comments
 (0)