use uX::from instead of _ as uX in non - const contexts

This commit is contained in:
bendn 2025-04-29 13:51:45 +07:00
parent 2cd37831b0
commit 8373bb17d6
No known key found for this signature in database
GPG key ID: 0D9D3A2A3B2A93D6
4 changed files with 130 additions and 46 deletions

View file

@ -30,6 +30,7 @@ impl<'a, 'tcx> UnnecessaryTransmuteChecker<'a, 'tcx> {
function: &Operand<'tcx>,
arg: String,
span: Span,
is_in_const: bool,
) -> Option<Error> {
let fn_sig = function.ty(self.body, self.tcx).fn_sig(self.tcx).skip_binder();
let [input] = fn_sig.inputs() else { return None };
@ -97,8 +98,14 @@ impl<'a, 'tcx> UnnecessaryTransmuteChecker<'a, 'tcx> {
)),
// uNN → fNN
(Uint(_), Float(ty)) => err(format!("{}::from_bits({arg})", ty.name_str())),
// bool → { x8 }
(Bool, Int(..) | Uint(..)) => err(format!("({arg}) as {}", fn_sig.output())),
// bool → { x8 } in const context since `From::from` is not const yet
// FIXME: is it possible to know when the parentheses arent necessary?
// FIXME(const_traits): Remove this when From::from is constified?
(Bool, Int(..) | Uint(..)) if is_in_const => {
err(format!("({arg}) as {}", fn_sig.output()))
}
// " using `x8::from`
(Bool, Int(..) | Uint(..)) => err(format!("{}::from({arg})", fn_sig.output())),
_ => return None,
})
}
@ -114,7 +121,13 @@ impl<'tcx> Visitor<'tcx> for UnnecessaryTransmuteChecker<'_, 'tcx> {
&& self.tcx.is_intrinsic(func_def_id, sym::transmute)
&& let span = self.body.source_info(location).span
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(arg)
&& let Some(lint) = self.is_unnecessary_transmute(func, snippet, span)
&& let def_id = self.body.source.def_id()
&& let Some(lint) = self.is_unnecessary_transmute(
func,
snippet,
span,
self.tcx.hir_body_const_context(def_id.expect_local()).is_some(),
)
&& let Some(hir_id) = terminator.source_info.scope.lint_root(&self.body.source_scopes)
{
self.tcx.emit_node_span_lint(UNNECESSARY_TRANSMUTES, hir_id, span, lint);

View file

@ -8,7 +8,27 @@ pub fn bytes_at_home(x: u32) -> [u8; 4] {
//~^ ERROR
}
pub const fn intinator_const(from: bool) -> u8 {
unsafe { (from) as u8 }
//~^ ERROR
}
pub static X: u8 = unsafe { (true) as u8 };
//~^ ERROR
pub const Y: u8 = unsafe { (true) as u8 };
//~^ ERROR
pub struct Z {}
impl Z {
pub const fn intinator_assoc(x: bool) -> u8 {
unsafe { (x) as u8 }
//~^ ERROR
}
}
fn main() {
const { unsafe { (true) as u8 } };
//~^ ERROR
unsafe {
let x: u16 = u16::from_ne_bytes(*b"01");
//~^ ERROR
@ -83,12 +103,12 @@ fn main() {
let z: bool = transmute(1u8);
// clippy
let z: u8 = (z) as u8;
let z: u8 = u8::from(z);
//~^ ERROR
let z: bool = transmute(1i8);
// clippy
let z: i8 = (z) as i8;
let z: i8 = i8::from(z);
//~^ ERROR
}
}

View file

@ -8,7 +8,27 @@ pub fn bytes_at_home(x: u32) -> [u8; 4] {
//~^ ERROR
}
pub const fn intinator_const(from: bool) -> u8 {
unsafe { transmute(from) }
//~^ ERROR
}
pub static X: u8 = unsafe { transmute(true) };
//~^ ERROR
pub const Y: u8 = unsafe { transmute(true) };
//~^ ERROR
pub struct Z {}
impl Z {
pub const fn intinator_assoc(x: bool) -> u8 {
unsafe { transmute(x) }
//~^ ERROR
}
}
fn main() {
const { unsafe { transmute::<_, u8>(true) } };
//~^ ERROR
unsafe {
let x: u16 = transmute(*b"01");
//~^ ERROR

View file

@ -1,10 +1,9 @@
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:7:14
--> $DIR/unnecessary-transmutation.rs:16:29
|
LL | unsafe { transmute(x) }
| ^^^^^^^^^^^^ help: replace this with: `u32::to_ne_bytes(x)`
LL | pub static X: u8 = unsafe { transmute(true) };
| ^^^^^^^^^^^^^^^ help: replace this with: `(true) as u8`
|
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
note: the lint level is defined here
--> $DIR/unnecessary-transmutation.rs:2:9
|
@ -12,7 +11,33 @@ LL | #![deny(unnecessary_transmutes)]
| ^^^^^^^^^^^^^^^^^^^^^^
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:13:22
--> $DIR/unnecessary-transmutation.rs:18:28
|
LL | pub const Y: u8 = unsafe { transmute(true) };
| ^^^^^^^^^^^^^^^ help: replace this with: `(true) as u8`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:7:14
|
LL | unsafe { transmute(x) }
| ^^^^^^^^^^^^ help: replace this with: `u32::to_ne_bytes(x)`
|
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:12:14
|
LL | unsafe { transmute(from) }
| ^^^^^^^^^^^^^^^ help: replace this with: `(from) as u8`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:24:18
|
LL | unsafe { transmute(x) }
| ^^^^^^^^^^^^ help: replace this with: `(x) as u8`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:33:22
|
LL | let x: u16 = transmute(*b"01");
| ^^^^^^^^^^^^^^^^^ help: replace this with: `u16::from_ne_bytes(*b"01")`
@ -20,7 +45,7 @@ LL | let x: u16 = transmute(*b"01");
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:15:26
--> $DIR/unnecessary-transmutation.rs:35:26
|
LL | let x: [u8; 2] = transmute(x);
| ^^^^^^^^^^^^ help: replace this with: `u16::to_ne_bytes(x)`
@ -28,7 +53,7 @@ LL | let x: [u8; 2] = transmute(x);
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:17:22
--> $DIR/unnecessary-transmutation.rs:37:22
|
LL | let x: u32 = transmute(*b"0123");
| ^^^^^^^^^^^^^^^^^^^ help: replace this with: `u32::from_ne_bytes(*b"0123")`
@ -36,7 +61,7 @@ LL | let x: u32 = transmute(*b"0123");
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:19:26
--> $DIR/unnecessary-transmutation.rs:39:26
|
LL | let x: [u8; 4] = transmute(x);
| ^^^^^^^^^^^^ help: replace this with: `u32::to_ne_bytes(x)`
@ -44,7 +69,7 @@ LL | let x: [u8; 4] = transmute(x);
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:21:22
--> $DIR/unnecessary-transmutation.rs:41:22
|
LL | let x: u64 = transmute(*b"feriscat");
| ^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `u64::from_ne_bytes(*b"feriscat")`
@ -52,7 +77,7 @@ LL | let x: u64 = transmute(*b"feriscat");
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:23:26
--> $DIR/unnecessary-transmutation.rs:43:26
|
LL | let x: [u8; 8] = transmute(x);
| ^^^^^^^^^^^^ help: replace this with: `u64::to_ne_bytes(x)`
@ -60,7 +85,7 @@ LL | let x: [u8; 8] = transmute(x);
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:26:22
--> $DIR/unnecessary-transmutation.rs:46:22
|
LL | let y: i16 = transmute(*b"01");
| ^^^^^^^^^^^^^^^^^ help: replace this with: `i16::from_ne_bytes(*b"01")`
@ -68,7 +93,7 @@ LL | let y: i16 = transmute(*b"01");
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:28:26
--> $DIR/unnecessary-transmutation.rs:48:26
|
LL | let y: [u8; 2] = transmute(y);
| ^^^^^^^^^^^^ help: replace this with: `i16::to_ne_bytes(y)`
@ -76,7 +101,7 @@ LL | let y: [u8; 2] = transmute(y);
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:30:22
--> $DIR/unnecessary-transmutation.rs:50:22
|
LL | let y: i32 = transmute(*b"0123");
| ^^^^^^^^^^^^^^^^^^^ help: replace this with: `i32::from_ne_bytes(*b"0123")`
@ -84,7 +109,7 @@ LL | let y: i32 = transmute(*b"0123");
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:32:26
--> $DIR/unnecessary-transmutation.rs:52:26
|
LL | let y: [u8; 4] = transmute(y);
| ^^^^^^^^^^^^ help: replace this with: `i32::to_ne_bytes(y)`
@ -92,7 +117,7 @@ LL | let y: [u8; 4] = transmute(y);
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:34:22
--> $DIR/unnecessary-transmutation.rs:54:22
|
LL | let y: i64 = transmute(*b"feriscat");
| ^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `i64::from_ne_bytes(*b"feriscat")`
@ -100,7 +125,7 @@ LL | let y: i64 = transmute(*b"feriscat");
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:36:26
--> $DIR/unnecessary-transmutation.rs:56:26
|
LL | let y: [u8; 8] = transmute(y);
| ^^^^^^^^^^^^ help: replace this with: `i64::to_ne_bytes(y)`
@ -108,7 +133,7 @@ LL | let y: [u8; 8] = transmute(y);
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:39:22
--> $DIR/unnecessary-transmutation.rs:59:22
|
LL | let z: f32 = transmute(*b"0123");
| ^^^^^^^^^^^^^^^^^^^ help: replace this with: `f32::from_ne_bytes(*b"0123")`
@ -116,7 +141,7 @@ LL | let z: f32 = transmute(*b"0123");
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:41:26
--> $DIR/unnecessary-transmutation.rs:61:26
|
LL | let z: [u8; 4] = transmute(z);
| ^^^^^^^^^^^^ help: replace this with: `f32::to_ne_bytes(z)`
@ -124,7 +149,7 @@ LL | let z: [u8; 4] = transmute(z);
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:43:22
--> $DIR/unnecessary-transmutation.rs:63:22
|
LL | let z: f64 = transmute(*b"feriscat");
| ^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `f64::from_ne_bytes(*b"feriscat")`
@ -132,7 +157,7 @@ LL | let z: f64 = transmute(*b"feriscat");
= help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:45:26
--> $DIR/unnecessary-transmutation.rs:65:26
|
LL | let z: [u8; 8] = transmute(z);
| ^^^^^^^^^^^^ help: replace this with: `f64::to_ne_bytes(z)`
@ -140,13 +165,13 @@ LL | let z: [u8; 8] = transmute(z);
= help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:48:22
--> $DIR/unnecessary-transmutation.rs:68:22
|
LL | let y: u32 = transmute('🦀');
| ^^^^^^^^^^^^^^^ help: replace this with: `u32::from('🦀')`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:50:23
--> $DIR/unnecessary-transmutation.rs:70:23
|
LL | let y: char = transmute(y);
| ^^^^^^^^^^^^ help: replace this with: `char::from_u32_unchecked(y)`
@ -154,13 +179,13 @@ LL | let y: char = transmute(y);
= help: consider `char::from_u32(…).unwrap()`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:52:22
--> $DIR/unnecessary-transmutation.rs:72:22
|
LL | let y: i32 = transmute('🐱');
| ^^^^^^^^^^^^^^^ help: replace this with: `u32::from('🐱').cast_signed()`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:54:23
--> $DIR/unnecessary-transmutation.rs:74:23
|
LL | let y: char = transmute(y);
| ^^^^^^^^^^^^ help: replace this with: `char::from_u32_unchecked(i32::cast_unsigned(y))`
@ -168,88 +193,94 @@ LL | let y: char = transmute(y);
= help: consider `char::from_u32(i32::cast_unsigned(…)).unwrap()`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:57:22
--> $DIR/unnecessary-transmutation.rs:77:22
|
LL | let x: u16 = transmute(8i16);
| ^^^^^^^^^^^^^^^ help: replace this with: `i16::cast_unsigned(8i16)`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:59:22
--> $DIR/unnecessary-transmutation.rs:79:22
|
LL | let x: i16 = transmute(x);
| ^^^^^^^^^^^^ help: replace this with: `u16::cast_signed(x)`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:61:22
--> $DIR/unnecessary-transmutation.rs:81:22
|
LL | let x: u32 = transmute(4i32);
| ^^^^^^^^^^^^^^^ help: replace this with: `i32::cast_unsigned(4i32)`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:63:22
--> $DIR/unnecessary-transmutation.rs:83:22
|
LL | let x: i32 = transmute(x);
| ^^^^^^^^^^^^ help: replace this with: `u32::cast_signed(x)`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:65:22
--> $DIR/unnecessary-transmutation.rs:85:22
|
LL | let x: u64 = transmute(7i64);
| ^^^^^^^^^^^^^^^ help: replace this with: `i64::cast_unsigned(7i64)`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:67:22
--> $DIR/unnecessary-transmutation.rs:87:22
|
LL | let x: i64 = transmute(x);
| ^^^^^^^^^^^^ help: replace this with: `u64::cast_signed(x)`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:70:22
--> $DIR/unnecessary-transmutation.rs:90:22
|
LL | let y: f32 = transmute(1u32);
| ^^^^^^^^^^^^^^^ help: replace this with: `f32::from_bits(1u32)`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:72:22
--> $DIR/unnecessary-transmutation.rs:92:22
|
LL | let y: u32 = transmute(y);
| ^^^^^^^^^^^^ help: replace this with: `f32::to_bits(y)`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:74:22
--> $DIR/unnecessary-transmutation.rs:94:22
|
LL | let y: f64 = transmute(3u64);
| ^^^^^^^^^^^^^^^ help: replace this with: `f64::from_bits(3u64)`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:76:22
--> $DIR/unnecessary-transmutation.rs:96:22
|
LL | let y: u64 = transmute(2.0);
| ^^^^^^^^^^^^^^ help: replace this with: `f64::to_bits(2.0)`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:79:22
--> $DIR/unnecessary-transmutation.rs:99:22
|
LL | let y: f64 = transmute(1i64);
| ^^^^^^^^^^^^^^^ help: replace this with: `f64::from_bits(i64::cast_unsigned(1i64))`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:81:22
--> $DIR/unnecessary-transmutation.rs:101:22
|
LL | let y: i64 = transmute(1f64);
| ^^^^^^^^^^^^^^^ help: replace this with: `f64::to_bits(1f64).cast_signed()`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:86:21
--> $DIR/unnecessary-transmutation.rs:106:21
|
LL | let z: u8 = transmute(z);
| ^^^^^^^^^^^^ help: replace this with: `(z) as u8`
| ^^^^^^^^^^^^ help: replace this with: `u8::from(z)`
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:91:21
--> $DIR/unnecessary-transmutation.rs:111:21
|
LL | let z: i8 = transmute(z);
| ^^^^^^^^^^^^ help: replace this with: `(z) as i8`
| ^^^^^^^^^^^^ help: replace this with: `i8::from(z)`
error: aborting due to 35 previous errors
error: unnecessary transmute
--> $DIR/unnecessary-transmutation.rs:30:22
|
LL | const { unsafe { transmute::<_, u8>(true) } };
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `(true) as u8`
error: aborting due to 40 previous errors