Don't warn int-to-char transmutes in const contexts

This commit is contained in:
SabrinaJewson 2022-03-30 18:47:50 +01:00
parent fe7254ff6f
commit d6f05c6a89
No known key found for this signature in database
GPG key ID: 3D5438FFA5F05564
4 changed files with 32 additions and 26 deletions

View file

@ -410,9 +410,10 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
if let Some(def_id) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id();
if cx.tcx.is_diagnostic_item(sym::transmute, def_id);
then {
// Avoid suggesting from/to bits and dereferencing raw pointers in const contexts.
// See https://github.com/rust-lang/rust/issues/73736 for progress on making them `const fn`.
// And see https://github.com/rust-lang/rust/issues/51911 for dereferencing raw pointers.
// Avoid suggesting non-const operations in const contexts:
// - from/to bits (https://github.com/rust-lang/rust/issues/73736)
// - dereferencing raw pointers (https://github.com/rust-lang/rust/issues/51911)
// - char conversions (https://github.com/rust-lang/rust/issues/89259)
let const_context = in_constant(cx, e.hir_id);
let from_ty = cx.typeck_results().expr_ty_adjusted(arg);
@ -427,7 +428,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
let linted = wrong_transmute::check(cx, e, from_ty, to_ty)
| crosspointer_transmute::check(cx, e, from_ty, to_ty)
| transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, arg, qpath)
| transmute_int_to_char::check(cx, e, from_ty, to_ty, arg)
| transmute_int_to_char::check(cx, e, from_ty, to_ty, arg, const_context)
| transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context)
| transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg)
| transmute_int_to_bool::check(cx, e, from_ty, to_ty, arg)

View file

@ -15,9 +15,10 @@ pub(super) fn check<'tcx>(
from_ty: Ty<'tcx>,
to_ty: Ty<'tcx>,
arg: &'tcx Expr<'_>,
const_context: bool,
) -> bool {
match (&from_ty.kind(), &to_ty.kind()) {
(ty::Int(ty::IntTy::I32) | ty::Uint(ty::UintTy::U32), &ty::Char) => {
(ty::Int(ty::IntTy::I32) | ty::Uint(ty::UintTy::U32), &ty::Char) if !const_context => {
span_lint_and_then(
cx,
TRANSMUTE_INT_TO_CHAR,

View file

@ -73,6 +73,10 @@ fn crosspointer() {
fn int_to_char() {
let _: char = unsafe { std::mem::transmute(0_u32) };
let _: char = unsafe { std::mem::transmute(0_i32) };
// These shouldn't warn
const _: char = unsafe { std::mem::transmute(0_u32) };
const _: char = unsafe { std::mem::transmute(0_i32) };
}
#[warn(clippy::transmute_int_to_bool)]

View file

@ -107,7 +107,7 @@ LL | let _: char = unsafe { std::mem::transmute(0_i32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_i32 as u32).unwrap()`
error: transmute from a `u8` to a `bool`
--> $DIR/transmute.rs:80:28
--> $DIR/transmute.rs:84:28
|
LL | let _: bool = unsafe { std::mem::transmute(0_u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `0_u8 != 0`
@ -115,7 +115,7 @@ LL | let _: bool = unsafe { std::mem::transmute(0_u8) };
= note: `-D clippy::transmute-int-to-bool` implied by `-D warnings`
error: transmute from a `u32` to a `f32`
--> $DIR/transmute.rs:86:31
--> $DIR/transmute.rs:90:31
|
LL | let _: f32 = unsafe { std::mem::transmute(0_u32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)`
@ -123,25 +123,25 @@ LL | let _: f32 = unsafe { std::mem::transmute(0_u32) };
= note: `-D clippy::transmute-int-to-float` implied by `-D warnings`
error: transmute from a `i32` to a `f32`
--> $DIR/transmute.rs:87:31
--> $DIR/transmute.rs:91:31
|
LL | let _: f32 = unsafe { std::mem::transmute(0_i32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)`
error: transmute from a `u64` to a `f64`
--> $DIR/transmute.rs:88:31
--> $DIR/transmute.rs:92:31
|
LL | let _: f64 = unsafe { std::mem::transmute(0_u64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_u64)`
error: transmute from a `i64` to a `f64`
--> $DIR/transmute.rs:89:31
--> $DIR/transmute.rs:93:31
|
LL | let _: f64 = unsafe { std::mem::transmute(0_i64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)`
error: transmute from a `u8` to a `[u8; 1]`
--> $DIR/transmute.rs:109:30
--> $DIR/transmute.rs:113:30
|
LL | let _: [u8; 1] = std::mem::transmute(0u8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
@ -149,85 +149,85 @@ LL | let _: [u8; 1] = std::mem::transmute(0u8);
= note: `-D clippy::transmute-num-to-bytes` implied by `-D warnings`
error: transmute from a `u32` to a `[u8; 4]`
--> $DIR/transmute.rs:110:30
--> $DIR/transmute.rs:114:30
|
LL | let _: [u8; 4] = std::mem::transmute(0u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
error: transmute from a `u128` to a `[u8; 16]`
--> $DIR/transmute.rs:111:31
--> $DIR/transmute.rs:115:31
|
LL | let _: [u8; 16] = std::mem::transmute(0u128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
error: transmute from a `i8` to a `[u8; 1]`
--> $DIR/transmute.rs:112:30
--> $DIR/transmute.rs:116:30
|
LL | let _: [u8; 1] = std::mem::transmute(0i8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
error: transmute from a `i32` to a `[u8; 4]`
--> $DIR/transmute.rs:113:30
--> $DIR/transmute.rs:117:30
|
LL | let _: [u8; 4] = std::mem::transmute(0i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
error: transmute from a `i128` to a `[u8; 16]`
--> $DIR/transmute.rs:114:31
--> $DIR/transmute.rs:118:31
|
LL | let _: [u8; 16] = std::mem::transmute(0i128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
error: transmute from a `f32` to a `[u8; 4]`
--> $DIR/transmute.rs:115:30
--> $DIR/transmute.rs:119:30
|
LL | let _: [u8; 4] = std::mem::transmute(0.0f32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()`
error: transmute from a `f64` to a `[u8; 8]`
--> $DIR/transmute.rs:116:30
--> $DIR/transmute.rs:120:30
|
LL | let _: [u8; 8] = std::mem::transmute(0.0f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()`
error: transmute from a `u8` to a `[u8; 1]`
--> $DIR/transmute.rs:121:30
--> $DIR/transmute.rs:125:30
|
LL | let _: [u8; 1] = std::mem::transmute(0u8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
error: transmute from a `u32` to a `[u8; 4]`
--> $DIR/transmute.rs:122:30
--> $DIR/transmute.rs:126:30
|
LL | let _: [u8; 4] = std::mem::transmute(0u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
error: transmute from a `u128` to a `[u8; 16]`
--> $DIR/transmute.rs:123:31
--> $DIR/transmute.rs:127:31
|
LL | let _: [u8; 16] = std::mem::transmute(0u128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
error: transmute from a `i8` to a `[u8; 1]`
--> $DIR/transmute.rs:124:30
--> $DIR/transmute.rs:128:30
|
LL | let _: [u8; 1] = std::mem::transmute(0i8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
error: transmute from a `i32` to a `[u8; 4]`
--> $DIR/transmute.rs:125:30
--> $DIR/transmute.rs:129:30
|
LL | let _: [u8; 4] = std::mem::transmute(0i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
error: transmute from a `i128` to a `[u8; 16]`
--> $DIR/transmute.rs:126:31
--> $DIR/transmute.rs:130:31
|
LL | let _: [u8; 16] = std::mem::transmute(0i128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
error: transmute from a `&[u8]` to a `&str`
--> $DIR/transmute.rs:134:28
--> $DIR/transmute.rs:138:28
|
LL | let _: &str = unsafe { std::mem::transmute(b) };
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(b).unwrap()`
@ -235,7 +235,7 @@ LL | let _: &str = unsafe { std::mem::transmute(b) };
= note: `-D clippy::transmute-bytes-to-str` implied by `-D warnings`
error: transmute from a `&mut [u8]` to a `&mut str`
--> $DIR/transmute.rs:135:32
--> $DIR/transmute.rs:139:32
|
LL | let _: &mut str = unsafe { std::mem::transmute(mb) };
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`