Skip to content

Commit c85ceea

Browse files
committed
Auto merge of #10821 - Centri3:unnecessary_operation_cast_underscore, r=dswij
Emit `unnecessary_cast` on raw pointers as well Supersedes(?) #10782, since this and #10567 will cover the original issue. Does not lint on type aliases or inferred types. changelog: [`unnecessary_cast`]: Also emit on casts between raw pointers with the same type and constness
2 parents 00001d6 + d7a98f5 commit c85ceea

12 files changed

+188
-56
lines changed

clippy_lints/src/casts/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ declare_clippy_lint! {
174174

175175
declare_clippy_lint! {
176176
/// ### What it does
177-
/// Checks for casts to the same type, casts of int literals to integer types
178-
/// and casts of float literals to float types.
177+
/// Checks for casts to the same type, casts of int literals to integer types, casts of float
178+
/// literals to float types and casts between raw pointers without changing type or constness.
179179
///
180180
/// ### Why is this bad?
181181
/// It's just unnecessary.

clippy_lints/src/casts/unnecessary_cast.rs

+34-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::numeric_literal::NumericLiteral;
33
use clippy_utils::source::snippet_opt;
4-
use clippy_utils::{get_parent_expr, path_to_local};
4+
use clippy_utils::{get_parent_expr, is_ty_alias, path_to_local};
55
use if_chain::if_chain;
66
use rustc_ast::{LitFloatType, LitIntType, LitKind};
77
use rustc_errors::Applicability;
@@ -20,19 +20,49 @@ pub(super) fn check<'tcx>(
2020
cast_from: Ty<'tcx>,
2121
cast_to: Ty<'tcx>,
2222
) -> bool {
23+
let cast_str = snippet_opt(cx, cast_expr.span).unwrap_or_default();
24+
25+
if_chain! {
26+
if let ty::RawPtr(..) = cast_from.kind();
27+
// check both mutability and type are the same
28+
if cast_from.kind() == cast_to.kind();
29+
if let ExprKind::Cast(_, cast_to_hir) = expr.kind;
30+
then {
31+
if_chain! {
32+
if let TyKind::Path(qpath) = cast_to_hir.kind;
33+
if is_ty_alias(&qpath);
34+
then {
35+
return false;
36+
}
37+
}
38+
39+
if let TyKind::Infer = cast_to_hir.kind {
40+
return false;
41+
}
42+
43+
span_lint_and_sugg(
44+
cx,
45+
UNNECESSARY_CAST,
46+
expr.span,
47+
&format!("casting raw pointers to the same type and constness is unnecessary (`{cast_from}` -> `{cast_to}`)"),
48+
"try",
49+
cast_str.clone(),
50+
Applicability::MachineApplicable,
51+
);
52+
}
53+
}
54+
2355
// skip non-primitive type cast
2456
if_chain! {
2557
if let ExprKind::Cast(_, cast_to) = expr.kind;
2658
if let TyKind::Path(QPath::Resolved(_, path)) = &cast_to.kind;
2759
if let Res::PrimTy(_) = path.res;
2860
then {}
2961
else {
30-
return false
62+
return false;
3163
}
3264
}
3365

34-
let cast_str = snippet_opt(cx, cast_expr.span).unwrap_or_default();
35-
3666
if let Some(lit) = get_numeric_literal(cast_expr) {
3767
let literal_str = &cast_str;
3868

tests/ui/as_ptr_cast_mut.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![allow(unused)]
22
#![warn(clippy::as_ptr_cast_mut)]
3-
#![allow(clippy::wrong_self_convention)]
3+
#![allow(clippy::wrong_self_convention, clippy::unnecessary_cast)]
44

55
struct MutPtrWrapper(Vec<u8>);
66
impl MutPtrWrapper {

tests/ui/cast_slice_different_sizes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![allow(clippy::let_unit_value)]
1+
#![allow(clippy::let_unit_value, clippy::unnecessary_cast)]
22

33
fn main() {
44
let x: [i32; 3] = [1_i32, 2, 3];

tests/ui/crashes/ice-1782.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![allow(dead_code, unused_variables)]
2+
#![allow(clippy::unnecessary_cast)]
23

34
/// Should not trigger an ICE in `SpanlessEq` / `consts::constant`
45
///

tests/ui/from_raw_with_void_ptr.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![warn(clippy::from_raw_with_void_ptr)]
2+
#![allow(clippy::unnecessary_cast)]
23

34
use std::ffi::c_void;
45
use std::rc::Rc;

tests/ui/from_raw_with_void_ptr.stderr

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,60 @@
11
error: creating a `Box` from a void raw pointer
2-
--> $DIR/from_raw_with_void_ptr.rs:10:22
2+
--> $DIR/from_raw_with_void_ptr.rs:11:22
33
|
44
LL | let _ = unsafe { Box::from_raw(ptr) };
55
| ^^^^^^^^^^^^^^^^^^
66
|
77
help: cast this to a pointer of the appropriate type
8-
--> $DIR/from_raw_with_void_ptr.rs:10:36
8+
--> $DIR/from_raw_with_void_ptr.rs:11:36
99
|
1010
LL | let _ = unsafe { Box::from_raw(ptr) };
1111
| ^^^
1212
= note: `-D clippy::from-raw-with-void-ptr` implied by `-D warnings`
1313

1414
error: creating a `Rc` from a void raw pointer
15-
--> $DIR/from_raw_with_void_ptr.rs:21:22
15+
--> $DIR/from_raw_with_void_ptr.rs:22:22
1616
|
1717
LL | let _ = unsafe { Rc::from_raw(ptr) };
1818
| ^^^^^^^^^^^^^^^^^
1919
|
2020
help: cast this to a pointer of the appropriate type
21-
--> $DIR/from_raw_with_void_ptr.rs:21:35
21+
--> $DIR/from_raw_with_void_ptr.rs:22:35
2222
|
2323
LL | let _ = unsafe { Rc::from_raw(ptr) };
2424
| ^^^
2525

2626
error: creating a `Arc` from a void raw pointer
27-
--> $DIR/from_raw_with_void_ptr.rs:25:22
27+
--> $DIR/from_raw_with_void_ptr.rs:26:22
2828
|
2929
LL | let _ = unsafe { Arc::from_raw(ptr) };
3030
| ^^^^^^^^^^^^^^^^^^
3131
|
3232
help: cast this to a pointer of the appropriate type
33-
--> $DIR/from_raw_with_void_ptr.rs:25:36
33+
--> $DIR/from_raw_with_void_ptr.rs:26:36
3434
|
3535
LL | let _ = unsafe { Arc::from_raw(ptr) };
3636
| ^^^
3737

3838
error: creating a `Weak` from a void raw pointer
39-
--> $DIR/from_raw_with_void_ptr.rs:29:22
39+
--> $DIR/from_raw_with_void_ptr.rs:30:22
4040
|
4141
LL | let _ = unsafe { std::rc::Weak::from_raw(ptr) };
4242
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4343
|
4444
help: cast this to a pointer of the appropriate type
45-
--> $DIR/from_raw_with_void_ptr.rs:29:46
45+
--> $DIR/from_raw_with_void_ptr.rs:30:46
4646
|
4747
LL | let _ = unsafe { std::rc::Weak::from_raw(ptr) };
4848
| ^^^
4949

5050
error: creating a `Weak` from a void raw pointer
51-
--> $DIR/from_raw_with_void_ptr.rs:33:22
51+
--> $DIR/from_raw_with_void_ptr.rs:34:22
5252
|
5353
LL | let _ = unsafe { std::sync::Weak::from_raw(ptr) };
5454
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5555
|
5656
help: cast this to a pointer of the appropriate type
57-
--> $DIR/from_raw_with_void_ptr.rs:33:48
57+
--> $DIR/from_raw_with_void_ptr.rs:34:48
5858
|
5959
LL | let _ = unsafe { std::sync::Weak::from_raw(ptr) };
6060
| ^^^

tests/ui/transmute_ptr_to_ref.fixed

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//@run-rustfix
22

33
#![warn(clippy::transmute_ptr_to_ref)]
4-
#![allow(clippy::match_single_binding)]
4+
#![allow(clippy::match_single_binding, clippy::unnecessary_cast)]
55

66
unsafe fn _ptr_to_ref<T, U>(p: *const T, m: *mut T, o: *const U, om: *mut U) {
77
let _: &T = &*p;

tests/ui/transmute_ptr_to_ref.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//@run-rustfix
22

33
#![warn(clippy::transmute_ptr_to_ref)]
4-
#![allow(clippy::match_single_binding)]
4+
#![allow(clippy::match_single_binding, clippy::unnecessary_cast)]
55

66
unsafe fn _ptr_to_ref<T, U>(p: *const T, m: *mut T, o: *const U, om: *mut U) {
77
let _: &T = std::mem::transmute(p);

tests/ui/unnecessary_cast.fixed

+30-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
//@run-rustfix
22
#![warn(clippy::unnecessary_cast)]
33
#![allow(
4-
unused_must_use,
4+
unused,
55
clippy::borrow_as_ptr,
66
clippy::no_effect,
77
clippy::nonstandard_macro_braces,
88
clippy::unnecessary_operation
99
)]
1010

11+
type PtrConstU8 = *const u8;
12+
type PtrMutU8 = *mut u8;
13+
14+
fn owo<T>(ptr: *const T) -> *const T {
15+
ptr
16+
}
17+
18+
fn uwu<T, U>(ptr: *const T) -> *const U {
19+
ptr as *const U
20+
}
21+
1122
#[rustfmt::skip]
1223
fn main() {
1324
// Test cast_unnecessary
@@ -22,6 +33,24 @@ fn main() {
2233
1_i32;
2334
1_f32;
2435

36+
let _: *mut u8 = [1u8, 2].as_ptr() as *mut u8;
37+
38+
[1u8, 2].as_ptr();
39+
[1u8, 2].as_ptr() as *mut u8;
40+
[1u8, 2].as_mut_ptr();
41+
[1u8, 2].as_mut_ptr() as *const u8;
42+
[1u8, 2].as_ptr() as PtrConstU8;
43+
[1u8, 2].as_ptr() as PtrMutU8;
44+
[1u8, 2].as_mut_ptr() as PtrMutU8;
45+
[1u8, 2].as_mut_ptr() as PtrConstU8;
46+
let _: *const u8 = [1u8, 2].as_ptr() as _;
47+
let _: *mut u8 = [1u8, 2].as_mut_ptr() as _;
48+
49+
owo::<u32>([1u32].as_ptr());
50+
uwu::<u32, u8>([1u32].as_ptr());
51+
// this will not lint in the function body even though they have the same type, instead here
52+
uwu::<u32, u32>([1u32].as_ptr());
53+
2554
// macro version
2655
macro_rules! foo {
2756
($a:ident, $b:ident) => {

tests/ui/unnecessary_cast.rs

+30-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
//@run-rustfix
22
#![warn(clippy::unnecessary_cast)]
33
#![allow(
4-
unused_must_use,
4+
unused,
55
clippy::borrow_as_ptr,
66
clippy::no_effect,
77
clippy::nonstandard_macro_braces,
88
clippy::unnecessary_operation
99
)]
1010

11+
type PtrConstU8 = *const u8;
12+
type PtrMutU8 = *mut u8;
13+
14+
fn owo<T>(ptr: *const T) -> *const T {
15+
ptr as *const T
16+
}
17+
18+
fn uwu<T, U>(ptr: *const T) -> *const U {
19+
ptr as *const U
20+
}
21+
1122
#[rustfmt::skip]
1223
fn main() {
1324
// Test cast_unnecessary
@@ -22,6 +33,24 @@ fn main() {
2233
1_i32 as i32;
2334
1_f32 as f32;
2435

36+
let _: *mut u8 = [1u8, 2].as_ptr() as *const u8 as *mut u8;
37+
38+
[1u8, 2].as_ptr() as *const u8;
39+
[1u8, 2].as_ptr() as *mut u8;
40+
[1u8, 2].as_mut_ptr() as *mut u8;
41+
[1u8, 2].as_mut_ptr() as *const u8;
42+
[1u8, 2].as_ptr() as PtrConstU8;
43+
[1u8, 2].as_ptr() as PtrMutU8;
44+
[1u8, 2].as_mut_ptr() as PtrMutU8;
45+
[1u8, 2].as_mut_ptr() as PtrConstU8;
46+
let _: *const u8 = [1u8, 2].as_ptr() as _;
47+
let _: *mut u8 = [1u8, 2].as_mut_ptr() as _;
48+
49+
owo::<u32>([1u32].as_ptr()) as *const u32;
50+
uwu::<u32, u8>([1u32].as_ptr()) as *const u8;
51+
// this will not lint in the function body even though they have the same type, instead here
52+
uwu::<u32, u32>([1u32].as_ptr()) as *const u32;
53+
2554
// macro version
2655
macro_rules! foo {
2756
($a:ident, $b:ident) => {

0 commit comments

Comments
 (0)