Skip to content

Commit 9c9cca3

Browse files
committed
Don't lint useless_transmute on types with erased regions
1 parent 2466a05 commit 9c9cca3

File tree

3 files changed

+84
-70
lines changed

3 files changed

+84
-70
lines changed

clippy_lints/src/transmute/useless_transmute.rs

+25-22
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use clippy_utils::sugg;
44
use rustc_errors::Applicability;
55
use rustc_hir::Expr;
66
use rustc_lint::LateContext;
7-
use rustc_middle::ty::{self, Ty};
7+
use rustc_middle::ty::{self, Ty, TypeFoldable};
88

99
/// Checks for `useless_transmute` lint.
1010
/// Returns `true` if it's triggered, otherwise returns `false`.
@@ -16,7 +16,7 @@ pub(super) fn check<'tcx>(
1616
arg: &'tcx Expr<'_>,
1717
) -> bool {
1818
match (&from_ty.kind(), &to_ty.kind()) {
19-
_ if from_ty == to_ty => {
19+
_ if from_ty == to_ty && !from_ty.has_erased_regions() => {
2020
span_lint(
2121
cx,
2222
USELESS_TRANSMUTE,
@@ -26,28 +26,31 @@ pub(super) fn check<'tcx>(
2626
true
2727
},
2828
(ty::Ref(_, rty, rty_mutbl), ty::RawPtr(ptr_ty)) => {
29-
span_lint_and_then(
30-
cx,
31-
USELESS_TRANSMUTE,
32-
e.span,
33-
"transmute from a reference to a pointer",
34-
|diag| {
35-
if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) {
36-
let rty_and_mut = ty::TypeAndMut {
37-
ty: *rty,
38-
mutbl: *rty_mutbl,
39-
};
29+
// No way to give the correct suggestion here. Avoid linting for now.
30+
if !rty.has_erased_regions() {
31+
span_lint_and_then(
32+
cx,
33+
USELESS_TRANSMUTE,
34+
e.span,
35+
"transmute from a reference to a pointer",
36+
|diag| {
37+
if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) {
38+
let rty_and_mut = ty::TypeAndMut {
39+
ty: *rty,
40+
mutbl: *rty_mutbl,
41+
};
4042

41-
let sugg = if *ptr_ty == rty_and_mut {
42-
arg.as_ty(to_ty)
43-
} else {
44-
arg.as_ty(cx.tcx.mk_ptr(rty_and_mut)).as_ty(to_ty)
45-
};
43+
let sugg = if *ptr_ty == rty_and_mut {
44+
arg.as_ty(to_ty)
45+
} else {
46+
arg.as_ty(cx.tcx.mk_ptr(rty_and_mut)).as_ty(to_ty)
47+
};
4648

47-
diag.span_suggestion(e.span, "try", sugg.to_string(), Applicability::Unspecified);
48-
}
49-
},
50-
);
49+
diag.span_suggestion(e.span, "try", sugg.to_string(), Applicability::Unspecified);
50+
}
51+
},
52+
);
53+
}
5154
true
5255
},
5356
(ty::Int(_) | ty::Uint(_), ty::RawPtr(_)) => {

tests/ui/transmute.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ fn my_vec() -> MyVec<i32> {
1616
#[allow(clippy::needless_lifetimes, clippy::transmute_ptr_to_ptr)]
1717
#[warn(clippy::useless_transmute)]
1818
unsafe fn _generic<'a, T, U: 'a>(t: &'a T) {
19-
let _: &'a T = core::intrinsics::transmute(t);
19+
// FIXME: should lint
20+
// let _: &'a T = core::intrinsics::transmute(t);
2021

2122
let _: &'a U = core::intrinsics::transmute(t);
2223

@@ -48,6 +49,22 @@ fn useless() {
4849

4950
let _ = (1 + 1_usize) as *const usize;
5051
}
52+
53+
unsafe fn _f<'a, 'b>(x: &'a u32) -> &'b u32 {
54+
std::mem::transmute(x)
55+
}
56+
57+
unsafe fn _f2<'a, 'b>(x: *const (dyn Iterator<Item = u32> + 'a)) -> *const (dyn Iterator<Item = u32> + 'b) {
58+
std::mem::transmute(x)
59+
}
60+
61+
unsafe fn _f3<'a, 'b>(x: fn(&'a u32)) -> fn(&'b u32) {
62+
std::mem::transmute(x)
63+
}
64+
65+
unsafe fn _f4<'a, 'b>(x: std::borrow::Cow<'a, str>) -> std::borrow::Cow<'b, str> {
66+
std::mem::transmute(x)
67+
}
5168
}
5269

5370
struct Usize(usize);

tests/ui/transmute.stderr

+41-47
Original file line numberDiff line numberDiff line change
@@ -1,250 +1,244 @@
1-
error: transmute from a type (`&T`) to itself
2-
--> $DIR/transmute.rs:19:20
3-
|
4-
LL | let _: &'a T = core::intrinsics::transmute(t);
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6-
|
7-
= note: `-D clippy::useless-transmute` implied by `-D warnings`
8-
91
error: transmute from a reference to a pointer
10-
--> $DIR/transmute.rs:23:23
2+
--> $DIR/transmute.rs:24:23
113
|
124
LL | let _: *const T = core::intrinsics::transmute(t);
135
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T`
6+
|
7+
= note: `-D clippy::useless-transmute` implied by `-D warnings`
148

159
error: transmute from a reference to a pointer
16-
--> $DIR/transmute.rs:25:21
10+
--> $DIR/transmute.rs:26:21
1711
|
1812
LL | let _: *mut T = core::intrinsics::transmute(t);
1913
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *mut T`
2014

2115
error: transmute from a reference to a pointer
22-
--> $DIR/transmute.rs:27:23
16+
--> $DIR/transmute.rs:28:23
2317
|
2418
LL | let _: *const U = core::intrinsics::transmute(t);
2519
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *const U`
2620

2721
error: transmute from a type (`std::vec::Vec<i32>`) to itself
28-
--> $DIR/transmute.rs:33:27
22+
--> $DIR/transmute.rs:34:27
2923
|
3024
LL | let _: Vec<i32> = core::intrinsics::transmute(my_vec());
3125
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3226

3327
error: transmute from a type (`std::vec::Vec<i32>`) to itself
34-
--> $DIR/transmute.rs:35:27
28+
--> $DIR/transmute.rs:36:27
3529
|
3630
LL | let _: Vec<i32> = core::mem::transmute(my_vec());
3731
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3832

3933
error: transmute from a type (`std::vec::Vec<i32>`) to itself
40-
--> $DIR/transmute.rs:37:27
34+
--> $DIR/transmute.rs:38:27
4135
|
4236
LL | let _: Vec<i32> = std::intrinsics::transmute(my_vec());
4337
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4438

4539
error: transmute from a type (`std::vec::Vec<i32>`) to itself
46-
--> $DIR/transmute.rs:39:27
40+
--> $DIR/transmute.rs:40:27
4741
|
4842
LL | let _: Vec<i32> = std::mem::transmute(my_vec());
4943
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5044

5145
error: transmute from a type (`std::vec::Vec<i32>`) to itself
52-
--> $DIR/transmute.rs:41:27
46+
--> $DIR/transmute.rs:42:27
5347
|
5448
LL | let _: Vec<i32> = my_transmute(my_vec());
5549
| ^^^^^^^^^^^^^^^^^^^^^^
5650

5751
error: transmute from an integer to a pointer
58-
--> $DIR/transmute.rs:43:31
52+
--> $DIR/transmute.rs:44:31
5953
|
6054
LL | let _: *const usize = std::mem::transmute(5_isize);
6155
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `5_isize as *const usize`
6256

6357
error: transmute from an integer to a pointer
64-
--> $DIR/transmute.rs:47:31
58+
--> $DIR/transmute.rs:48:31
6559
|
6660
LL | let _: *const usize = std::mem::transmute(1 + 1usize);
6761
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(1 + 1usize) as *const usize`
6862

6963
error: transmute from a type (`*const Usize`) to the type that it points to (`Usize`)
70-
--> $DIR/transmute.rs:62:24
64+
--> $DIR/transmute.rs:79:24
7165
|
7266
LL | let _: Usize = core::intrinsics::transmute(int_const_ptr);
7367
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7468
|
7569
= note: `-D clippy::crosspointer-transmute` implied by `-D warnings`
7670

7771
error: transmute from a type (`*mut Usize`) to the type that it points to (`Usize`)
78-
--> $DIR/transmute.rs:64:24
72+
--> $DIR/transmute.rs:81:24
7973
|
8074
LL | let _: Usize = core::intrinsics::transmute(int_mut_ptr);
8175
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8276

8377
error: transmute from a type (`Usize`) to a pointer to that type (`*const Usize`)
84-
--> $DIR/transmute.rs:66:31
78+
--> $DIR/transmute.rs:83:31
8579
|
8680
LL | let _: *const Usize = core::intrinsics::transmute(my_int());
8781
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8882

8983
error: transmute from a type (`Usize`) to a pointer to that type (`*mut Usize`)
90-
--> $DIR/transmute.rs:68:29
84+
--> $DIR/transmute.rs:85:29
9185
|
9286
LL | let _: *mut Usize = core::intrinsics::transmute(my_int());
9387
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9488

9589
error: transmute from a `u32` to a `char`
96-
--> $DIR/transmute.rs:74:28
90+
--> $DIR/transmute.rs:91:28
9791
|
9892
LL | let _: char = unsafe { std::mem::transmute(0_u32) };
9993
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_u32).unwrap()`
10094
|
10195
= note: `-D clippy::transmute-int-to-char` implied by `-D warnings`
10296

10397
error: transmute from a `i32` to a `char`
104-
--> $DIR/transmute.rs:75:28
98+
--> $DIR/transmute.rs:92:28
10599
|
106100
LL | let _: char = unsafe { std::mem::transmute(0_i32) };
107101
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_i32 as u32).unwrap()`
108102

109103
error: transmute from a `u8` to a `bool`
110-
--> $DIR/transmute.rs:84:28
104+
--> $DIR/transmute.rs:101:28
111105
|
112106
LL | let _: bool = unsafe { std::mem::transmute(0_u8) };
113107
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `0_u8 != 0`
114108
|
115109
= note: `-D clippy::transmute-int-to-bool` implied by `-D warnings`
116110

117111
error: transmute from a `u32` to a `f32`
118-
--> $DIR/transmute.rs:90:31
112+
--> $DIR/transmute.rs:107:31
119113
|
120114
LL | let _: f32 = unsafe { std::mem::transmute(0_u32) };
121115
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)`
122116
|
123117
= note: `-D clippy::transmute-int-to-float` implied by `-D warnings`
124118

125119
error: transmute from a `i32` to a `f32`
126-
--> $DIR/transmute.rs:91:31
120+
--> $DIR/transmute.rs:108:31
127121
|
128122
LL | let _: f32 = unsafe { std::mem::transmute(0_i32) };
129123
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)`
130124

131125
error: transmute from a `u64` to a `f64`
132-
--> $DIR/transmute.rs:92:31
126+
--> $DIR/transmute.rs:109:31
133127
|
134128
LL | let _: f64 = unsafe { std::mem::transmute(0_u64) };
135129
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_u64)`
136130

137131
error: transmute from a `i64` to a `f64`
138-
--> $DIR/transmute.rs:93:31
132+
--> $DIR/transmute.rs:110:31
139133
|
140134
LL | let _: f64 = unsafe { std::mem::transmute(0_i64) };
141135
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)`
142136

143137
error: transmute from a `u8` to a `[u8; 1]`
144-
--> $DIR/transmute.rs:113:30
138+
--> $DIR/transmute.rs:130:30
145139
|
146140
LL | let _: [u8; 1] = std::mem::transmute(0u8);
147141
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
148142
|
149143
= note: `-D clippy::transmute-num-to-bytes` implied by `-D warnings`
150144

151145
error: transmute from a `u32` to a `[u8; 4]`
152-
--> $DIR/transmute.rs:114:30
146+
--> $DIR/transmute.rs:131:30
153147
|
154148
LL | let _: [u8; 4] = std::mem::transmute(0u32);
155149
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
156150

157151
error: transmute from a `u128` to a `[u8; 16]`
158-
--> $DIR/transmute.rs:115:31
152+
--> $DIR/transmute.rs:132:31
159153
|
160154
LL | let _: [u8; 16] = std::mem::transmute(0u128);
161155
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
162156

163157
error: transmute from a `i8` to a `[u8; 1]`
164-
--> $DIR/transmute.rs:116:30
158+
--> $DIR/transmute.rs:133:30
165159
|
166160
LL | let _: [u8; 1] = std::mem::transmute(0i8);
167161
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
168162

169163
error: transmute from a `i32` to a `[u8; 4]`
170-
--> $DIR/transmute.rs:117:30
164+
--> $DIR/transmute.rs:134:30
171165
|
172166
LL | let _: [u8; 4] = std::mem::transmute(0i32);
173167
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
174168

175169
error: transmute from a `i128` to a `[u8; 16]`
176-
--> $DIR/transmute.rs:118:31
170+
--> $DIR/transmute.rs:135:31
177171
|
178172
LL | let _: [u8; 16] = std::mem::transmute(0i128);
179173
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
180174

181175
error: transmute from a `f32` to a `[u8; 4]`
182-
--> $DIR/transmute.rs:119:30
176+
--> $DIR/transmute.rs:136:30
183177
|
184178
LL | let _: [u8; 4] = std::mem::transmute(0.0f32);
185179
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()`
186180

187181
error: transmute from a `f64` to a `[u8; 8]`
188-
--> $DIR/transmute.rs:120:30
182+
--> $DIR/transmute.rs:137:30
189183
|
190184
LL | let _: [u8; 8] = std::mem::transmute(0.0f64);
191185
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()`
192186

193187
error: transmute from a `u8` to a `[u8; 1]`
194-
--> $DIR/transmute.rs:125:30
188+
--> $DIR/transmute.rs:142:30
195189
|
196190
LL | let _: [u8; 1] = std::mem::transmute(0u8);
197191
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
198192

199193
error: transmute from a `u32` to a `[u8; 4]`
200-
--> $DIR/transmute.rs:126:30
194+
--> $DIR/transmute.rs:143:30
201195
|
202196
LL | let _: [u8; 4] = std::mem::transmute(0u32);
203197
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
204198

205199
error: transmute from a `u128` to a `[u8; 16]`
206-
--> $DIR/transmute.rs:127:31
200+
--> $DIR/transmute.rs:144:31
207201
|
208202
LL | let _: [u8; 16] = std::mem::transmute(0u128);
209203
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
210204

211205
error: transmute from a `i8` to a `[u8; 1]`
212-
--> $DIR/transmute.rs:128:30
206+
--> $DIR/transmute.rs:145:30
213207
|
214208
LL | let _: [u8; 1] = std::mem::transmute(0i8);
215209
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
216210

217211
error: transmute from a `i32` to a `[u8; 4]`
218-
--> $DIR/transmute.rs:129:30
212+
--> $DIR/transmute.rs:146:30
219213
|
220214
LL | let _: [u8; 4] = std::mem::transmute(0i32);
221215
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
222216

223217
error: transmute from a `i128` to a `[u8; 16]`
224-
--> $DIR/transmute.rs:130:31
218+
--> $DIR/transmute.rs:147:31
225219
|
226220
LL | let _: [u8; 16] = std::mem::transmute(0i128);
227221
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
228222

229223
error: transmute from a `&[u8]` to a `&str`
230-
--> $DIR/transmute.rs:140:28
224+
--> $DIR/transmute.rs:157:28
231225
|
232226
LL | let _: &str = unsafe { std::mem::transmute(B) };
233227
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()`
234228
|
235229
= note: `-D clippy::transmute-bytes-to-str` implied by `-D warnings`
236230

237231
error: transmute from a `&mut [u8]` to a `&mut str`
238-
--> $DIR/transmute.rs:141:32
232+
--> $DIR/transmute.rs:158:32
239233
|
240234
LL | let _: &mut str = unsafe { std::mem::transmute(mb) };
241235
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`
242236

243237
error: transmute from a `&[u8]` to a `&str`
244-
--> $DIR/transmute.rs:142:30
238+
--> $DIR/transmute.rs:159:30
245239
|
246240
LL | const _: &str = unsafe { std::mem::transmute(B) };
247241
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)`
248242

249-
error: aborting due to 39 previous errors
243+
error: aborting due to 38 previous errors
250244

0 commit comments

Comments
 (0)