Divide FN_TO_NUMERIC lint into two.
FN_TO_NUMERIC_CAST_WITH_TRUNCATION is correctness check FN_TO_NUMERIC_CAST is only style check
This commit is contained in:
parent
ded2576957
commit
24ab207671
@ -679,9 +679,9 @@ fn is_unit_literal(expr: &Expr) -> bool {
|
||||
"cast to the same type, e.g. `x as i32` where `x: i32`"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for casts of a function pointer to a numeric type except `usize`.
|
||||
/// **What it does:** Checks for casts of a function pointer to a numeric type not enough to store address.
|
||||
///
|
||||
/// **Why is this bad?** Casting a function pointer to something other than `usize` could truncate the address value.
|
||||
/// **Why is this bad?** Casting a function pointer to not eligable type could truncate the address value.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
@ -691,8 +691,25 @@ fn is_unit_literal(expr: &Expr) -> bool {
|
||||
/// let _ = test_fn as i32
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
pub FN_TO_NUMERIC_CAST,
|
||||
pub FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
|
||||
correctness,
|
||||
"cast function pointer to the numeric type with value truncation"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for casts of a function pointer to a numeric type except `usize`.
|
||||
///
|
||||
/// **Why is this bad?** Casting a function pointer to something other than `usize` is not a good style.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn test_fn() -> i16;
|
||||
/// let _ = test_fn as i128
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
pub FN_TO_NUMERIC_CAST,
|
||||
style,
|
||||
"cast function pointer to the numeric type"
|
||||
}
|
||||
|
||||
@ -909,7 +926,8 @@ fn get_lints(&self) -> LintArray {
|
||||
CAST_LOSSLESS,
|
||||
UNNECESSARY_CAST,
|
||||
CAST_PTR_ALIGNMENT,
|
||||
FN_TO_NUMERIC_CAST
|
||||
FN_TO_NUMERIC_CAST,
|
||||
FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -998,14 +1016,28 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
ty::TyFnDef(..) |
|
||||
ty::TyFnPtr(..) => {
|
||||
if cast_to.is_numeric() && cast_to.sty != ty::TyUint(UintTy::Usize){
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
FN_TO_NUMERIC_CAST,
|
||||
expr.span,
|
||||
&format!("casting a `{}` to `{}` may truncate the function address value.", cast_from, cast_to),
|
||||
"if you need the address of the function, consider",
|
||||
format!("{} as usize", &snippet(cx, ex.span, "x"))
|
||||
);
|
||||
let to_nbits = int_ty_to_nbits(cast_to, cx.tcx);
|
||||
let pointer_nbits = cx.tcx.data_layout.pointer_size.bits();
|
||||
if to_nbits < pointer_nbits || (to_nbits == pointer_nbits && cast_to.is_signed()) {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
|
||||
expr.span,
|
||||
&format!("casting a `{}` to `{}` may truncate the function address value.", cast_from, cast_to),
|
||||
"if you need the address of the function, consider",
|
||||
format!("{} as usize", &snippet(cx, ex.span, "x"))
|
||||
);
|
||||
} else {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
FN_TO_NUMERIC_CAST,
|
||||
expr.span,
|
||||
&format!("casting a `{}` to `{}` is bad style.", cast_from, cast_to),
|
||||
"if you need the address of the function, consider",
|
||||
format!("{} as usize", &snippet(cx, ex.span, "x"))
|
||||
);
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
|
@ -9,8 +9,14 @@ fn bar() -> i32 {
|
||||
|
||||
fn main() {
|
||||
let x = Foo::A;
|
||||
let y = x as i32;
|
||||
let y1 = Foo::A as i32;
|
||||
|
||||
let z = bar as u32;
|
||||
let _y = x as i32;
|
||||
let _y1 = Foo::A as i32;
|
||||
let _y = x as u32;
|
||||
let _z = bar as u32;
|
||||
let _y = bar as i64;
|
||||
let _y = bar as u64;
|
||||
let _z = Foo::A as i128;
|
||||
let _z = Foo::A as u128;
|
||||
let _z = bar as i128;
|
||||
let _z = bar as u128;
|
||||
}
|
||||
|
@ -1,22 +1,66 @@
|
||||
error: casting a `fn(usize) -> Foo {Foo::A}` to `i32` may truncate the function address value.
|
||||
--> $DIR/types_fn_to_int.rs:12:13
|
||||
--> $DIR/types_fn_to_int.rs:12:14
|
||||
|
|
||||
12 | let y = x as i32;
|
||||
| ^^^^^^^^ help: if you need the address of the function, consider: `x as usize`
|
||||
12 | let _y = x as i32;
|
||||
| ^^^^^^^^ help: if you need the address of the function, consider: `x as usize`
|
||||
|
|
||||
= note: #[deny(fn_to_numeric_cast)] on by default
|
||||
= note: #[deny(fn_to_numeric_cast_with_truncation)] on by default
|
||||
|
||||
error: casting a `fn(usize) -> Foo {Foo::A}` to `i32` may truncate the function address value.
|
||||
--> $DIR/types_fn_to_int.rs:13:14
|
||||
--> $DIR/types_fn_to_int.rs:13:15
|
||||
|
|
||||
13 | let y1 = Foo::A as i32;
|
||||
| ^^^^^^^^^^^^^ help: if you need the address of the function, consider: `Foo::A as usize`
|
||||
13 | let _y1 = Foo::A as i32;
|
||||
| ^^^^^^^^^^^^^ help: if you need the address of the function, consider: `Foo::A as usize`
|
||||
|
||||
error: casting a `fn(usize) -> Foo {Foo::A}` to `u32` may truncate the function address value.
|
||||
--> $DIR/types_fn_to_int.rs:14:14
|
||||
|
|
||||
14 | let _y = x as u32;
|
||||
| ^^^^^^^^ help: if you need the address of the function, consider: `x as usize`
|
||||
|
||||
error: casting a `fn() -> i32 {bar}` to `u32` may truncate the function address value.
|
||||
--> $DIR/types_fn_to_int.rs:15:13
|
||||
--> $DIR/types_fn_to_int.rs:15:14
|
||||
|
|
||||
15 | let z = bar as u32;
|
||||
| ^^^^^^^^^^ help: if you need the address of the function, consider: `bar as usize`
|
||||
15 | let _z = bar as u32;
|
||||
| ^^^^^^^^^^ help: if you need the address of the function, consider: `bar as usize`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: casting a `fn() -> i32 {bar}` to `i64` may truncate the function address value.
|
||||
--> $DIR/types_fn_to_int.rs:16:14
|
||||
|
|
||||
16 | let _y = bar as i64;
|
||||
| ^^^^^^^^^^ help: if you need the address of the function, consider: `bar as usize`
|
||||
|
||||
error: casting a `fn() -> i32 {bar}` to `u64` is bad style.
|
||||
--> $DIR/types_fn_to_int.rs:17:14
|
||||
|
|
||||
17 | let _y = bar as u64;
|
||||
| ^^^^^^^^^^ help: if you need the address of the function, consider: `bar as usize`
|
||||
|
|
||||
= note: `-D fn-to-numeric-cast` implied by `-D warnings`
|
||||
|
||||
error: casting a `fn(usize) -> Foo {Foo::A}` to `i128` is bad style.
|
||||
--> $DIR/types_fn_to_int.rs:18:14
|
||||
|
|
||||
18 | let _z = Foo::A as i128;
|
||||
| ^^^^^^^^^^^^^^ help: if you need the address of the function, consider: `Foo::A as usize`
|
||||
|
||||
error: casting a `fn(usize) -> Foo {Foo::A}` to `u128` is bad style.
|
||||
--> $DIR/types_fn_to_int.rs:19:14
|
||||
|
|
||||
19 | let _z = Foo::A as u128;
|
||||
| ^^^^^^^^^^^^^^ help: if you need the address of the function, consider: `Foo::A as usize`
|
||||
|
||||
error: casting a `fn() -> i32 {bar}` to `i128` is bad style.
|
||||
--> $DIR/types_fn_to_int.rs:20:14
|
||||
|
|
||||
20 | let _z = bar as i128;
|
||||
| ^^^^^^^^^^^ help: if you need the address of the function, consider: `bar as usize`
|
||||
|
||||
error: casting a `fn() -> i32 {bar}` to `u128` is bad style.
|
||||
--> $DIR/types_fn_to_int.rs:21:14
|
||||
|
|
||||
21 | let _z = bar as u128;
|
||||
| ^^^^^^^^^^^ help: if you need the address of the function, consider: `bar as usize`
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user