Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions clippy_lints/src/transmute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion clippy_lints/src/transmute/transmute_int_to_char.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions tests/ui/transmute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
42 changes: 21 additions & 21 deletions tests/ui/transmute.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -107,135 +107,135 @@ 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`
|
= 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)`
|
= 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()`
|
= 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()`
|
= 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()`
Expand Down