Auto merge of #7805 - aDotInTheVoid:transmute-num-bits, r=camsteffen
Add lint transmute_num_to_bytes Closes #7803 changelog: [`transmute_num_to_bytes`] new lint
This commit is contained in:
commit
b9b11a96d2
@ -3025,6 +3025,7 @@ Released 2018-09-13
|
|||||||
[`transmute_int_to_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_bool
|
[`transmute_int_to_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_bool
|
||||||
[`transmute_int_to_char`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_char
|
[`transmute_int_to_char`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_char
|
||||||
[`transmute_int_to_float`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_float
|
[`transmute_int_to_float`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_float
|
||||||
|
[`transmute_num_to_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_num_to_bytes
|
||||||
[`transmute_ptr_to_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ptr
|
[`transmute_ptr_to_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ptr
|
||||||
[`transmute_ptr_to_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref
|
[`transmute_ptr_to_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref
|
||||||
[`transmutes_expressible_as_ptr_casts`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmutes_expressible_as_ptr_casts
|
[`transmutes_expressible_as_ptr_casts`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmutes_expressible_as_ptr_casts
|
||||||
|
@ -267,6 +267,7 @@
|
|||||||
LintId::of(transmute::TRANSMUTE_INT_TO_BOOL),
|
LintId::of(transmute::TRANSMUTE_INT_TO_BOOL),
|
||||||
LintId::of(transmute::TRANSMUTE_INT_TO_CHAR),
|
LintId::of(transmute::TRANSMUTE_INT_TO_CHAR),
|
||||||
LintId::of(transmute::TRANSMUTE_INT_TO_FLOAT),
|
LintId::of(transmute::TRANSMUTE_INT_TO_FLOAT),
|
||||||
|
LintId::of(transmute::TRANSMUTE_NUM_TO_BYTES),
|
||||||
LintId::of(transmute::TRANSMUTE_PTR_TO_REF),
|
LintId::of(transmute::TRANSMUTE_PTR_TO_REF),
|
||||||
LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
|
LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
|
||||||
LintId::of(transmute::WRONG_TRANSMUTE),
|
LintId::of(transmute::WRONG_TRANSMUTE),
|
||||||
|
@ -82,6 +82,7 @@
|
|||||||
LintId::of(transmute::TRANSMUTE_INT_TO_BOOL),
|
LintId::of(transmute::TRANSMUTE_INT_TO_BOOL),
|
||||||
LintId::of(transmute::TRANSMUTE_INT_TO_CHAR),
|
LintId::of(transmute::TRANSMUTE_INT_TO_CHAR),
|
||||||
LintId::of(transmute::TRANSMUTE_INT_TO_FLOAT),
|
LintId::of(transmute::TRANSMUTE_INT_TO_FLOAT),
|
||||||
|
LintId::of(transmute::TRANSMUTE_NUM_TO_BYTES),
|
||||||
LintId::of(transmute::TRANSMUTE_PTR_TO_REF),
|
LintId::of(transmute::TRANSMUTE_PTR_TO_REF),
|
||||||
LintId::of(types::BORROWED_BOX),
|
LintId::of(types::BORROWED_BOX),
|
||||||
LintId::of(types::TYPE_COMPLEXITY),
|
LintId::of(types::TYPE_COMPLEXITY),
|
||||||
|
@ -450,6 +450,7 @@
|
|||||||
transmute::TRANSMUTE_INT_TO_BOOL,
|
transmute::TRANSMUTE_INT_TO_BOOL,
|
||||||
transmute::TRANSMUTE_INT_TO_CHAR,
|
transmute::TRANSMUTE_INT_TO_CHAR,
|
||||||
transmute::TRANSMUTE_INT_TO_FLOAT,
|
transmute::TRANSMUTE_INT_TO_FLOAT,
|
||||||
|
transmute::TRANSMUTE_NUM_TO_BYTES,
|
||||||
transmute::TRANSMUTE_PTR_TO_PTR,
|
transmute::TRANSMUTE_PTR_TO_PTR,
|
||||||
transmute::TRANSMUTE_PTR_TO_REF,
|
transmute::TRANSMUTE_PTR_TO_REF,
|
||||||
transmute::UNSOUND_COLLECTION_TRANSMUTE,
|
transmute::UNSOUND_COLLECTION_TRANSMUTE,
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
mod transmute_int_to_bool;
|
mod transmute_int_to_bool;
|
||||||
mod transmute_int_to_char;
|
mod transmute_int_to_char;
|
||||||
mod transmute_int_to_float;
|
mod transmute_int_to_float;
|
||||||
|
mod transmute_num_to_bytes;
|
||||||
mod transmute_ptr_to_ptr;
|
mod transmute_ptr_to_ptr;
|
||||||
mod transmute_ptr_to_ref;
|
mod transmute_ptr_to_ref;
|
||||||
mod transmute_ref_to_ref;
|
mod transmute_ref_to_ref;
|
||||||
@ -261,6 +262,28 @@
|
|||||||
"transmutes from a float to an integer"
|
"transmutes from a float to an integer"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_clippy_lint! {
|
||||||
|
/// # What it does
|
||||||
|
/// Checks for transmutes from a number to an array of `u8`
|
||||||
|
///
|
||||||
|
/// ### Why this is bad?
|
||||||
|
/// Transmutes are dangerous and error-prone, whereas `to_ne_bytes`
|
||||||
|
/// is intuitive and safe.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
/// ```rust
|
||||||
|
/// unsafe {
|
||||||
|
/// let x: [u8; 8] = std::mem::transmute(1i64);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// // should be
|
||||||
|
/// let x: [u8; 8] = 0i64.to_ne_bytes();
|
||||||
|
/// ```
|
||||||
|
pub TRANSMUTE_NUM_TO_BYTES,
|
||||||
|
complexity,
|
||||||
|
"transmutes from a number to an array of `u8`"
|
||||||
|
}
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
/// ### What it does
|
/// ### What it does
|
||||||
/// Checks for transmutes from a pointer to a pointer, or
|
/// Checks for transmutes from a pointer to a pointer, or
|
||||||
@ -330,6 +353,7 @@
|
|||||||
TRANSMUTE_INT_TO_BOOL,
|
TRANSMUTE_INT_TO_BOOL,
|
||||||
TRANSMUTE_INT_TO_FLOAT,
|
TRANSMUTE_INT_TO_FLOAT,
|
||||||
TRANSMUTE_FLOAT_TO_INT,
|
TRANSMUTE_FLOAT_TO_INT,
|
||||||
|
TRANSMUTE_NUM_TO_BYTES,
|
||||||
UNSOUND_COLLECTION_TRANSMUTE,
|
UNSOUND_COLLECTION_TRANSMUTE,
|
||||||
TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,
|
TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,
|
||||||
]);
|
]);
|
||||||
@ -365,6 +389,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
|
|||||||
linted |= transmute_int_to_bool::check(cx, e, from_ty, to_ty, args);
|
linted |= transmute_int_to_bool::check(cx, e, from_ty, to_ty, args);
|
||||||
linted |= transmute_int_to_float::check(cx, e, from_ty, to_ty, args, const_context);
|
linted |= transmute_int_to_float::check(cx, e, from_ty, to_ty, args, const_context);
|
||||||
linted |= transmute_float_to_int::check(cx, e, from_ty, to_ty, args, const_context);
|
linted |= transmute_float_to_int::check(cx, e, from_ty, to_ty, args, const_context);
|
||||||
|
linted |= transmute_num_to_bytes::check(cx, e, from_ty, to_ty, args, const_context);
|
||||||
linted |= unsound_collection_transmute::check(cx, e, from_ty, to_ty);
|
linted |= unsound_collection_transmute::check(cx, e, from_ty, to_ty);
|
||||||
|
|
||||||
if !linted {
|
if !linted {
|
||||||
|
49
clippy_lints/src/transmute/transmute_num_to_bytes.rs
Normal file
49
clippy_lints/src/transmute/transmute_num_to_bytes.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
use super::TRANSMUTE_NUM_TO_BYTES;
|
||||||
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
|
use clippy_utils::sugg;
|
||||||
|
use rustc_errors::Applicability;
|
||||||
|
use rustc_hir::Expr;
|
||||||
|
use rustc_lint::LateContext;
|
||||||
|
use rustc_middle::ty::{self, Ty, UintTy};
|
||||||
|
|
||||||
|
/// Checks for `transmute_int_to_float` lint.
|
||||||
|
/// Returns `true` if it's triggered, otherwise returns `false`.
|
||||||
|
pub(super) fn check<'tcx>(
|
||||||
|
cx: &LateContext<'tcx>,
|
||||||
|
e: &'tcx Expr<'_>,
|
||||||
|
from_ty: Ty<'tcx>,
|
||||||
|
to_ty: Ty<'tcx>,
|
||||||
|
args: &'tcx [Expr<'_>],
|
||||||
|
const_context: bool,
|
||||||
|
) -> bool {
|
||||||
|
match (&from_ty.kind(), &to_ty.kind()) {
|
||||||
|
(ty::Int(_) | ty::Uint(_) | ty::Float(_), ty::Array(arr_ty, _)) => {
|
||||||
|
if !matches!(arr_ty.kind(), ty::Uint(UintTy::U8)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if matches!(from_ty.kind(), ty::Float(_)) && const_context {
|
||||||
|
// TODO: Remove when const_float_bits_conv is stabilized
|
||||||
|
// rust#72447
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
span_lint_and_then(
|
||||||
|
cx,
|
||||||
|
TRANSMUTE_NUM_TO_BYTES,
|
||||||
|
e.span,
|
||||||
|
&format!("transmute from a `{}` to a `{}`", from_ty, to_ty),
|
||||||
|
|diag| {
|
||||||
|
let arg = sugg::Sugg::hir(cx, &args[0], "..");
|
||||||
|
diag.span_suggestion(
|
||||||
|
e.span,
|
||||||
|
"consider using `to_ne_bytes()`",
|
||||||
|
format!("{}.to_ne_bytes()", arg.to_string()),
|
||||||
|
Applicability::Unspecified,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
true
|
||||||
|
},
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
@ -103,6 +103,33 @@ const fn from_bits_64(v: u64) -> f64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod num_to_bytes {
|
||||||
|
fn test() {
|
||||||
|
unsafe {
|
||||||
|
let _: [u8; 1] = std::mem::transmute(0u8);
|
||||||
|
let _: [u8; 4] = std::mem::transmute(0u32);
|
||||||
|
let _: [u8; 16] = std::mem::transmute(0u128);
|
||||||
|
let _: [u8; 1] = std::mem::transmute(0i8);
|
||||||
|
let _: [u8; 4] = std::mem::transmute(0i32);
|
||||||
|
let _: [u8; 16] = std::mem::transmute(0i128);
|
||||||
|
let _: [u8; 4] = std::mem::transmute(0.0f32);
|
||||||
|
let _: [u8; 8] = std::mem::transmute(0.0f64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const fn test_const() {
|
||||||
|
unsafe {
|
||||||
|
let _: [u8; 1] = std::mem::transmute(0u8);
|
||||||
|
let _: [u8; 4] = std::mem::transmute(0u32);
|
||||||
|
let _: [u8; 16] = std::mem::transmute(0u128);
|
||||||
|
let _: [u8; 1] = std::mem::transmute(0i8);
|
||||||
|
let _: [u8; 4] = std::mem::transmute(0i32);
|
||||||
|
let _: [u8; 16] = std::mem::transmute(0i128);
|
||||||
|
let _: [u8; 4] = std::mem::transmute(0.0f32);
|
||||||
|
let _: [u8; 8] = std::mem::transmute(0.0f64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn bytes_to_str(b: &[u8], mb: &mut [u8]) {
|
fn bytes_to_str(b: &[u8], mb: &mut [u8]) {
|
||||||
let _: &str = unsafe { std::mem::transmute(b) };
|
let _: &str = unsafe { std::mem::transmute(b) };
|
||||||
let _: &mut str = unsafe { std::mem::transmute(mb) };
|
let _: &mut str = unsafe { std::mem::transmute(mb) };
|
||||||
|
@ -140,8 +140,94 @@ error: transmute from a `i64` to a `f64`
|
|||||||
LL | let _: f64 = unsafe { std::mem::transmute(0_i64) };
|
LL | let _: f64 = unsafe { std::mem::transmute(0_i64) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)`
|
||||||
|
|
||||||
|
error: transmute from a `u8` to a `[u8; 1]`
|
||||||
|
--> $DIR/transmute.rs:109: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
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
|
||||||
|
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
|
||||||
|
|
|
||||||
|
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`
|
error: transmute from a `&[u8]` to a `&str`
|
||||||
--> $DIR/transmute.rs:107:28
|
--> $DIR/transmute.rs:134:28
|
||||||
|
|
|
|
||||||
LL | let _: &str = unsafe { std::mem::transmute(b) };
|
LL | let _: &str = unsafe { std::mem::transmute(b) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(b).unwrap()`
|
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(b).unwrap()`
|
||||||
@ -149,10 +235,10 @@ LL | let _: &str = unsafe { std::mem::transmute(b) };
|
|||||||
= note: `-D clippy::transmute-bytes-to-str` implied by `-D warnings`
|
= note: `-D clippy::transmute-bytes-to-str` implied by `-D warnings`
|
||||||
|
|
||||||
error: transmute from a `&mut [u8]` to a `&mut str`
|
error: transmute from a `&mut [u8]` to a `&mut str`
|
||||||
--> $DIR/transmute.rs:108:32
|
--> $DIR/transmute.rs:135:32
|
||||||
|
|
|
|
||||||
LL | let _: &mut str = unsafe { std::mem::transmute(mb) };
|
LL | let _: &mut str = unsafe { std::mem::transmute(mb) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`
|
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`
|
||||||
|
|
||||||
error: aborting due to 24 previous errors
|
error: aborting due to 38 previous errors
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user