Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 17737d6

Browse files
committedApr 30, 2025··
use uX::from instead of _ as uX in non - const contexts
1 parent 427288b commit 17737d6

File tree

4 files changed

+133
-43
lines changed

4 files changed

+133
-43
lines changed
 

‎compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_hir::def::DefKind::*;
12
use rustc_middle::mir::visit::Visitor;
23
use rustc_middle::mir::{Body, Location, Operand, Terminator, TerminatorKind};
34
use rustc_middle::ty::*;
@@ -29,6 +30,7 @@ impl<'a, 'tcx> UnnecessaryTransmuteChecker<'a, 'tcx> {
2930
function: &Operand<'tcx>,
3031
arg: String,
3132
span: Span,
33+
is_in_const: bool,
3234
) -> Option<Error> {
3335
let fn_sig = function.ty(self.body, self.tcx).fn_sig(self.tcx).skip_binder();
3436
let [input] = fn_sig.inputs() else { return None };
@@ -69,9 +71,15 @@ impl<'a, 'tcx> UnnecessaryTransmuteChecker<'a, 'tcx> {
6971
(Float(ty), Uint(..)) => err(format!("{}::to_bits({arg})", ty.name_str())),
7072
// uNN → fNN
7173
(Uint(_), Float(ty)) => err(format!("{}::from_bits({arg})", ty.name_str())),
72-
// bool → { x8 }
73-
(Bool, Int(..) | Uint(..)) => err(format!("({arg}) as {}", fn_sig.output())),
74+
// bool → { x8 } in const context
75+
// is it possible to know when the parentheses arent necessary?
76+
(Bool, Int(..) | Uint(..)) if is_in_const => {
77+
err(format!("({arg}) as {}", fn_sig.output()))
78+
}
79+
// " using `x8::from`
80+
(Bool, Int(..) | Uint(..)) => err(format!("{}::from({arg})", fn_sig.output())),
7481
// u8 → bool
82+
// also want to fix parentheses, maybe
7583
(Uint(_), Bool) => err(format!("({arg} == 1)")),
7684
_ => return None,
7785
})
@@ -88,7 +96,18 @@ impl<'tcx> Visitor<'tcx> for UnnecessaryTransmuteChecker<'_, 'tcx> {
8896
&& self.tcx.is_intrinsic(func_def_id, sym::transmute)
8997
&& let span = self.body.source_info(location).span
9098
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(arg)
91-
&& let Some(lint) = self.is_unnecessary_transmute(func, snippet, span)
99+
&& let def_id = self.body.source.def_id()
100+
&& let Some(lint) = self.is_unnecessary_transmute(
101+
func,
102+
snippet,
103+
span,
104+
self.tcx.is_const_fn(def_id)
105+
|| self.tcx.is_conditionally_const(def_id)
106+
|| matches!(
107+
self.tcx.def_kind(def_id),
108+
AnonConst | Const | Static { .. } | AssocConst | InlineConst
109+
),
110+
)
92111
&& let Some(hir_id) = terminator.source_info.scope.lint_root(&self.body.source_scopes)
93112
{
94113
self.tcx.emit_node_span_lint(UNNECESSARY_TRANSMUTES, hir_id, span, lint);

‎tests/ui/transmute/unnecessary-transmutation.fixed

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,27 @@ pub fn bytes_at_home(x: u32) -> [u8; 4] {
88
//~^ ERROR
99
}
1010

11+
pub const fn intinator_const(from: bool) -> u8 {
12+
unsafe { (from) as u8 }
13+
//~^ ERROR
14+
}
15+
16+
pub static X: u8 = unsafe { (true) as u8 };
17+
//~^ ERROR
18+
pub const Y: u8 = unsafe { (true) as u8 };
19+
//~^ ERROR
20+
21+
pub struct Z {}
22+
impl Z {
23+
pub const fn intinator_assoc(x: bool) -> u8 {
24+
unsafe { (x) as u8 }
25+
//~^ ERROR
26+
}
27+
}
28+
1129
fn main() {
30+
const { unsafe { (true) as u8 } };
31+
//~^ ERROR
1232
unsafe {
1333
let x: u16 = u16::from_ne_bytes(*b"01");
1434
//~^ ERROR
@@ -74,12 +94,12 @@ fn main() {
7494

7595
let z: bool = (1u8 == 1);
7696
//~^ ERROR
77-
let z: u8 = (z) as u8;
97+
let z: u8 = u8::from(z);
7898
//~^ ERROR
7999

80100
let z: bool = transmute(1i8);
81101
// no error!
82-
let z: i8 = (z) as i8;
102+
let z: i8 = i8::from(z);
83103
//~^ ERROR
84104
}
85105
}

‎tests/ui/transmute/unnecessary-transmutation.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,27 @@ pub fn bytes_at_home(x: u32) -> [u8; 4] {
88
//~^ ERROR
99
}
1010

11+
pub const fn intinator_const(from: bool) -> u8 {
12+
unsafe { transmute(from) }
13+
//~^ ERROR
14+
}
15+
16+
pub static X: u8 = unsafe { transmute(true) };
17+
//~^ ERROR
18+
pub const Y: u8 = unsafe { transmute(true) };
19+
//~^ ERROR
20+
21+
pub struct Z {}
22+
impl Z {
23+
pub const fn intinator_assoc(x: bool) -> u8 {
24+
unsafe { transmute(x) }
25+
//~^ ERROR
26+
}
27+
}
28+
1129
fn main() {
30+
const { unsafe { transmute::<_, u8>(true) } };
31+
//~^ ERROR
1232
unsafe {
1333
let x: u16 = transmute(*b"01");
1434
//~^ ERROR
Lines changed: 69 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,235 +1,266 @@
11
error: unnecessary transmute
2-
--> $DIR/unnecessary-transmutation.rs:7:14
2+
--> $DIR/unnecessary-transmutation.rs:16:29
33
|
4-
LL | unsafe { transmute(x) }
5-
| ^^^^^^^^^^^^ help: replace this with: `u32::to_ne_bytes(x)`
4+
LL | pub static X: u8 = unsafe { transmute(true) };
5+
| ^^^^^^^^^^^^^^^ help: replace this with: `(true) as u8`
66
|
7-
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
87
note: the lint level is defined here
98
--> $DIR/unnecessary-transmutation.rs:2:9
109
|
1110
LL | #![deny(unnecessary_transmutes)]
1211
| ^^^^^^^^^^^^^^^^^^^^^^
1312

1413
error: unnecessary transmute
15-
--> $DIR/unnecessary-transmutation.rs:13:22
14+
--> $DIR/unnecessary-transmutation.rs:18:28
15+
|
16+
LL | pub const Y: u8 = unsafe { transmute(true) };
17+
| ^^^^^^^^^^^^^^^ help: replace this with: `(true) as u8`
18+
19+
error: unnecessary transmute
20+
--> $DIR/unnecessary-transmutation.rs:7:14
21+
|
22+
LL | unsafe { transmute(x) }
23+
| ^^^^^^^^^^^^ help: replace this with: `u32::to_ne_bytes(x)`
24+
|
25+
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
26+
27+
error: unnecessary transmute
28+
--> $DIR/unnecessary-transmutation.rs:12:14
29+
|
30+
LL | unsafe { transmute(from) }
31+
| ^^^^^^^^^^^^^^^ help: replace this with: `(from) as u8`
32+
33+
error: unnecessary transmute
34+
--> $DIR/unnecessary-transmutation.rs:24:18
35+
|
36+
LL | unsafe { transmute(x) }
37+
| ^^^^^^^^^^^^ help: replace this with: `(x) as u8`
38+
39+
error: unnecessary transmute
40+
--> $DIR/unnecessary-transmutation.rs:33:22
1641
|
1742
LL | let x: u16 = transmute(*b"01");
1843
| ^^^^^^^^^^^^^^^^^ help: replace this with: `u16::from_ne_bytes(*b"01")`
1944
|
2045
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
2146

2247
error: unnecessary transmute
23-
--> $DIR/unnecessary-transmutation.rs:15:26
48+
--> $DIR/unnecessary-transmutation.rs:35:26
2449
|
2550
LL | let x: [u8; 2] = transmute(x);
2651
| ^^^^^^^^^^^^ help: replace this with: `u16::to_ne_bytes(x)`
2752
|
2853
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
2954

3055
error: unnecessary transmute
31-
--> $DIR/unnecessary-transmutation.rs:17:22
56+
--> $DIR/unnecessary-transmutation.rs:37:22
3257
|
3358
LL | let x: u32 = transmute(*b"0123");
3459
| ^^^^^^^^^^^^^^^^^^^ help: replace this with: `u32::from_ne_bytes(*b"0123")`
3560
|
3661
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
3762

3863
error: unnecessary transmute
39-
--> $DIR/unnecessary-transmutation.rs:19:26
64+
--> $DIR/unnecessary-transmutation.rs:39:26
4065
|
4166
LL | let x: [u8; 4] = transmute(x);
4267
| ^^^^^^^^^^^^ help: replace this with: `u32::to_ne_bytes(x)`
4368
|
4469
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
4570

4671
error: unnecessary transmute
47-
--> $DIR/unnecessary-transmutation.rs:21:22
72+
--> $DIR/unnecessary-transmutation.rs:41:22
4873
|
4974
LL | let x: u64 = transmute(*b"feriscat");
5075
| ^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `u64::from_ne_bytes(*b"feriscat")`
5176
|
5277
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
5378

5479
error: unnecessary transmute
55-
--> $DIR/unnecessary-transmutation.rs:23:26
80+
--> $DIR/unnecessary-transmutation.rs:43:26
5681
|
5782
LL | let x: [u8; 8] = transmute(x);
5883
| ^^^^^^^^^^^^ help: replace this with: `u64::to_ne_bytes(x)`
5984
|
6085
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
6186

6287
error: unnecessary transmute
63-
--> $DIR/unnecessary-transmutation.rs:26:22
88+
--> $DIR/unnecessary-transmutation.rs:46:22
6489
|
6590
LL | let y: i16 = transmute(*b"01");
6691
| ^^^^^^^^^^^^^^^^^ help: replace this with: `i16::from_ne_bytes(*b"01")`
6792
|
6893
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
6994

7095
error: unnecessary transmute
71-
--> $DIR/unnecessary-transmutation.rs:28:26
96+
--> $DIR/unnecessary-transmutation.rs:48:26
7297
|
7398
LL | let y: [u8; 2] = transmute(y);
7499
| ^^^^^^^^^^^^ help: replace this with: `i16::to_ne_bytes(y)`
75100
|
76101
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
77102

78103
error: unnecessary transmute
79-
--> $DIR/unnecessary-transmutation.rs:30:22
104+
--> $DIR/unnecessary-transmutation.rs:50:22
80105
|
81106
LL | let y: i32 = transmute(*b"0123");
82107
| ^^^^^^^^^^^^^^^^^^^ help: replace this with: `i32::from_ne_bytes(*b"0123")`
83108
|
84109
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
85110

86111
error: unnecessary transmute
87-
--> $DIR/unnecessary-transmutation.rs:32:26
112+
--> $DIR/unnecessary-transmutation.rs:52:26
88113
|
89114
LL | let y: [u8; 4] = transmute(y);
90115
| ^^^^^^^^^^^^ help: replace this with: `i32::to_ne_bytes(y)`
91116
|
92117
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
93118

94119
error: unnecessary transmute
95-
--> $DIR/unnecessary-transmutation.rs:34:22
120+
--> $DIR/unnecessary-transmutation.rs:54:22
96121
|
97122
LL | let y: i64 = transmute(*b"feriscat");
98123
| ^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `i64::from_ne_bytes(*b"feriscat")`
99124
|
100125
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
101126

102127
error: unnecessary transmute
103-
--> $DIR/unnecessary-transmutation.rs:36:26
128+
--> $DIR/unnecessary-transmutation.rs:56:26
104129
|
105130
LL | let y: [u8; 8] = transmute(y);
106131
| ^^^^^^^^^^^^ help: replace this with: `i64::to_ne_bytes(y)`
107132
|
108133
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
109134

110135
error: unnecessary transmute
111-
--> $DIR/unnecessary-transmutation.rs:39:22
136+
--> $DIR/unnecessary-transmutation.rs:59:22
112137
|
113138
LL | let z: f32 = transmute(*b"0123");
114139
| ^^^^^^^^^^^^^^^^^^^ help: replace this with: `f32::from_ne_bytes(*b"0123")`
115140
|
116141
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
117142

118143
error: unnecessary transmute
119-
--> $DIR/unnecessary-transmutation.rs:41:26
144+
--> $DIR/unnecessary-transmutation.rs:61:26
120145
|
121146
LL | let z: [u8; 4] = transmute(z);
122147
| ^^^^^^^^^^^^ help: replace this with: `f32::to_ne_bytes(z)`
123148
|
124149
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
125150

126151
error: unnecessary transmute
127-
--> $DIR/unnecessary-transmutation.rs:43:22
152+
--> $DIR/unnecessary-transmutation.rs:63:22
128153
|
129154
LL | let z: f64 = transmute(*b"feriscat");
130155
| ^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `f64::from_ne_bytes(*b"feriscat")`
131156
|
132157
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
133158

134159
error: unnecessary transmute
135-
--> $DIR/unnecessary-transmutation.rs:45:26
160+
--> $DIR/unnecessary-transmutation.rs:65:26
136161
|
137162
LL | let z: [u8; 8] = transmute(z);
138163
| ^^^^^^^^^^^^ help: replace this with: `f64::to_ne_bytes(z)`
139164
|
140165
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
141166

142167
error: unnecessary transmute
143-
--> $DIR/unnecessary-transmutation.rs:48:22
168+
--> $DIR/unnecessary-transmutation.rs:68:22
144169
|
145170
LL | let y: u32 = transmute('🦀');
146171
| ^^^^^^^^^^^^^^^ help: replace this with: `u32::from('🦀')`
147172

148173
error: unnecessary transmute
149-
--> $DIR/unnecessary-transmutation.rs:50:23
174+
--> $DIR/unnecessary-transmutation.rs:70:23
150175
|
151176
LL | let y: char = transmute(y);
152177
| ^^^^^^^^^^^^ help: replace this with: `char::from_u32_unchecked(y)`
153178
|
154179
= help: consider `char::from_u32(…).unwrap()`
155180

156181
error: unnecessary transmute
157-
--> $DIR/unnecessary-transmutation.rs:53:22
182+
--> $DIR/unnecessary-transmutation.rs:73:22
158183
|
159184
LL | let x: u16 = transmute(8i16);
160185
| ^^^^^^^^^^^^^^^ help: replace this with: `i16::cast_unsigned(8i16)`
161186

162187
error: unnecessary transmute
163-
--> $DIR/unnecessary-transmutation.rs:55:22
188+
--> $DIR/unnecessary-transmutation.rs:75:22
164189
|
165190
LL | let x: i16 = transmute(x);
166191
| ^^^^^^^^^^^^ help: replace this with: `u16::cast_signed(x)`
167192

168193
error: unnecessary transmute
169-
--> $DIR/unnecessary-transmutation.rs:57:22
194+
--> $DIR/unnecessary-transmutation.rs:77:22
170195
|
171196
LL | let x: u32 = transmute(4i32);
172197
| ^^^^^^^^^^^^^^^ help: replace this with: `i32::cast_unsigned(4i32)`
173198

174199
error: unnecessary transmute
175-
--> $DIR/unnecessary-transmutation.rs:59:22
200+
--> $DIR/unnecessary-transmutation.rs:79:22
176201
|
177202
LL | let x: i32 = transmute(x);
178203
| ^^^^^^^^^^^^ help: replace this with: `u32::cast_signed(x)`
179204

180205
error: unnecessary transmute
181-
--> $DIR/unnecessary-transmutation.rs:61:22
206+
--> $DIR/unnecessary-transmutation.rs:81:22
182207
|
183208
LL | let x: u64 = transmute(7i64);
184209
| ^^^^^^^^^^^^^^^ help: replace this with: `i64::cast_unsigned(7i64)`
185210

186211
error: unnecessary transmute
187-
--> $DIR/unnecessary-transmutation.rs:63:22
212+
--> $DIR/unnecessary-transmutation.rs:83:22
188213
|
189214
LL | let x: i64 = transmute(x);
190215
| ^^^^^^^^^^^^ help: replace this with: `u64::cast_signed(x)`
191216

192217
error: unnecessary transmute
193-
--> $DIR/unnecessary-transmutation.rs:66:22
218+
--> $DIR/unnecessary-transmutation.rs:86:22
194219
|
195220
LL | let y: f32 = transmute(1u32);
196221
| ^^^^^^^^^^^^^^^ help: replace this with: `f32::from_bits(1u32)`
197222

198223
error: unnecessary transmute
199-
--> $DIR/unnecessary-transmutation.rs:68:22
224+
--> $DIR/unnecessary-transmutation.rs:88:22
200225
|
201226
LL | let y: u32 = transmute(y);
202227
| ^^^^^^^^^^^^ help: replace this with: `f32::to_bits(y)`
203228

204229
error: unnecessary transmute
205-
--> $DIR/unnecessary-transmutation.rs:70:22
230+
--> $DIR/unnecessary-transmutation.rs:90:22
206231
|
207232
LL | let y: f64 = transmute(3u64);
208233
| ^^^^^^^^^^^^^^^ help: replace this with: `f64::from_bits(3u64)`
209234

210235
error: unnecessary transmute
211-
--> $DIR/unnecessary-transmutation.rs:72:22
236+
--> $DIR/unnecessary-transmutation.rs:92:22
212237
|
213238
LL | let y: u64 = transmute(2.0);
214239
| ^^^^^^^^^^^^^^ help: replace this with: `f64::to_bits(2.0)`
215240

216241
error: unnecessary transmute
217-
--> $DIR/unnecessary-transmutation.rs:75:23
242+
--> $DIR/unnecessary-transmutation.rs:95:23
218243
|
219244
LL | let z: bool = transmute(1u8);
220245
| ^^^^^^^^^^^^^^ help: replace this with: `(1u8 == 1)`
221246

222247
error: unnecessary transmute
223-
--> $DIR/unnecessary-transmutation.rs:77:21
248+
--> $DIR/unnecessary-transmutation.rs:97:21
224249
|
225250
LL | let z: u8 = transmute(z);
226-
| ^^^^^^^^^^^^ help: replace this with: `(z) as u8`
251+
| ^^^^^^^^^^^^ help: replace this with: `u8::from(z)`
227252

228253
error: unnecessary transmute
229-
--> $DIR/unnecessary-transmutation.rs:82:21
254+
--> $DIR/unnecessary-transmutation.rs:102:21
230255
|
231256
LL | let z: i8 = transmute(z);
232-
| ^^^^^^^^^^^^ help: replace this with: `(z) as i8`
257+
| ^^^^^^^^^^^^ help: replace this with: `i8::from(z)`
258+
259+
error: unnecessary transmute
260+
--> $DIR/unnecessary-transmutation.rs:30:22
261+
|
262+
LL | const { unsafe { transmute::<_, u8>(true) } };
263+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `(true) as u8`
233264

234-
error: aborting due to 32 previous errors
265+
error: aborting due to 37 previous errors
235266

0 commit comments

Comments
 (0)
Please sign in to comment.