Skip to content
Open
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
14 changes: 12 additions & 2 deletions clippy_lints/src/transmute/transmute_ref_to_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::source::snippet;
use clippy_utils::{std_or_core, sugg};
use rustc_errors::Applicability;
use rustc_hir::{Expr, Mutability};
use rustc_hir::{Expr, ExprKind, Mutability, Node};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty};

Expand Down Expand Up @@ -58,11 +58,21 @@ pub(super) fn check<'tcx>(
let sugg_paren = arg
.as_ty(Ty::new_ptr(cx.tcx, ty_from, from_mutbl))
.as_ty(Ty::new_ptr(cx.tcx, ty_to, to_mutbl));
let sugg = if to_mutbl == Mutability::Mut {
let mut sugg = if to_mutbl == Mutability::Mut {
sugg_paren.mut_addr_deref()
} else {
sugg_paren.addr_deref()
};
// If the expression is a receiver of some kind of a projection, we'll need to wrap the
// replacement in parens
if let Node::Expr(parent) = cx.tcx.parent_hir_node(e.hir_id)
&& let ExprKind::Index(recv, ..)
| ExprKind::Field(recv, _)
| ExprKind::MethodCall(_, recv, ..) = parent.kind
&& recv.hir_id == e.hir_id
{
sugg = sugg.maybe_paren();
}
diag.span_suggestion(e.span, "try", sugg, Applicability::Unspecified);
}
},
Expand Down
29 changes: 28 additions & 1 deletion tests/ui/transmute_ptr_to_ptr.fixed
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
#![warn(clippy::transmute_ptr_to_ptr)]
#![allow(clippy::borrow_as_ptr, clippy::missing_transmute_annotations)]
#![allow(
clippy::borrow_as_ptr,
clippy::missing_transmute_annotations,
clippy::let_unit_value,
clippy::unnecessary_mut_passed,
mutable_transmutes,
invalid_reference_casting
)]

use std::mem::transmute;

Expand Down Expand Up @@ -117,4 +124,24 @@ fn msrv_1_65(ptr: *const u8, mut_ptr: *mut u8) {
}
}

fn issue15003(bs: &[u8]) {
unsafe {
(&mut *(bs as *const [u8] as *mut [u8]))[4] = 42;
//~^ transmute_ptr_to_ptr
let _ = (&mut *(bs as *const [u8] as *mut [u8])).len();
//~^ transmute_ptr_to_ptr
// NOTE: need to transmute into something we can then index into
let _ = (&mut *(bs as *const [u8] as *mut (u8, [u8]))).0;
//~^ transmute_ptr_to_ptr

// Don't add parens if the expression is not the receiver
struct S;
impl S {
fn foo(self, _: &mut [u8]) {}
}
let _ = S.foo(&mut *(bs as *const [u8] as *mut [u8]));
//~^ transmute_ptr_to_ptr
}
}

fn main() {}
29 changes: 28 additions & 1 deletion tests/ui/transmute_ptr_to_ptr.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
#![warn(clippy::transmute_ptr_to_ptr)]
#![allow(clippy::borrow_as_ptr, clippy::missing_transmute_annotations)]
#![allow(
clippy::borrow_as_ptr,
clippy::missing_transmute_annotations,
clippy::let_unit_value,
clippy::unnecessary_mut_passed,
mutable_transmutes,
invalid_reference_casting
)]

use std::mem::transmute;

Expand Down Expand Up @@ -117,4 +124,24 @@ fn msrv_1_65(ptr: *const u8, mut_ptr: *mut u8) {
}
}

fn issue15003(bs: &[u8]) {
unsafe {
transmute::<&[u8], &mut [u8]>(bs)[4] = 42;
//~^ transmute_ptr_to_ptr
let _ = transmute::<&[u8], &mut [u8]>(bs).len();
//~^ transmute_ptr_to_ptr
// NOTE: need to transmute into something we can then index into
let _ = transmute::<&[u8], &mut (u8, [u8])>(bs).0;
//~^ transmute_ptr_to_ptr

// Don't add parens if the expression is not the receiver
struct S;
impl S {
fn foo(self, _: &mut [u8]) {}
}
let _ = S.foo(transmute::<&[u8], &mut [u8]>(bs));
//~^ transmute_ptr_to_ptr
}
}

fn main() {}
58 changes: 41 additions & 17 deletions tests/ui/transmute_ptr_to_ptr.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: transmute from a pointer to a pointer
--> tests/ui/transmute_ptr_to_ptr.rs:32:29
--> tests/ui/transmute_ptr_to_ptr.rs:39:29
|
LL | let _: *const f32 = transmute(ptr);
| ^^^^^^^^^^^^^^
Expand All @@ -13,7 +13,7 @@ LL + let _: *const f32 = ptr.cast::<f32>();
|

error: transmute from a pointer to a pointer
--> tests/ui/transmute_ptr_to_ptr.rs:35:27
--> tests/ui/transmute_ptr_to_ptr.rs:42:27
|
LL | let _: *mut f32 = transmute(mut_ptr);
| ^^^^^^^^^^^^^^^^^^
Expand All @@ -25,37 +25,37 @@ LL + let _: *mut f32 = mut_ptr.cast::<f32>();
|

error: transmute from a reference to a reference
--> tests/ui/transmute_ptr_to_ptr.rs:39:23
--> tests/ui/transmute_ptr_to_ptr.rs:46:23
|
LL | let _: &f32 = transmute(&1u32);
| ^^^^^^^^^^^^^^^^ help: try: `&*(&1u32 as *const u32 as *const f32)`

error: transmute from a reference to a reference
--> tests/ui/transmute_ptr_to_ptr.rs:42:23
--> tests/ui/transmute_ptr_to_ptr.rs:49:23
|
LL | let _: &f32 = transmute(&1f64);
| ^^^^^^^^^^^^^^^^ help: try: `&*(&1f64 as *const f64 as *const f32)`

error: transmute from a reference to a reference
--> tests/ui/transmute_ptr_to_ptr.rs:47:27
--> tests/ui/transmute_ptr_to_ptr.rs:54:27
|
LL | let _: &mut f32 = transmute(&mut 1u32);
| ^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(&mut 1u32 as *mut u32 as *mut f32)`

error: transmute from a reference to a reference
--> tests/ui/transmute_ptr_to_ptr.rs:50:37
--> tests/ui/transmute_ptr_to_ptr.rs:57:37
|
LL | let _: &GenericParam<f32> = transmute(&GenericParam { t: 1u32 });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&GenericParam { t: 1u32 } as *const GenericParam<u32> as *const GenericParam<f32>)`

error: transmute from a reference to a reference
--> tests/ui/transmute_ptr_to_ptr.rs:54:27
--> tests/ui/transmute_ptr_to_ptr.rs:61:27
|
LL | let u8_ref: &u8 = transmute(u64_ref);
| ^^^^^^^^^^^^^^^^^^ help: try: `&*(u64_ref as *const u64 as *const u8)`

error: transmute from a pointer to a pointer
--> tests/ui/transmute_ptr_to_ptr.rs:57:29
--> tests/ui/transmute_ptr_to_ptr.rs:64:29
|
LL | let _: *const u32 = transmute(mut_ptr);
| ^^^^^^^^^^^^^^^^^^
Expand All @@ -67,7 +67,7 @@ LL + let _: *const u32 = mut_ptr.cast_const();
|

error: transmute from a pointer to a pointer
--> tests/ui/transmute_ptr_to_ptr.rs:60:27
--> tests/ui/transmute_ptr_to_ptr.rs:67:27
|
LL | let _: *mut u32 = transmute(ptr);
| ^^^^^^^^^^^^^^
Expand All @@ -79,7 +79,7 @@ LL + let _: *mut u32 = ptr.cast_mut();
|

error: transmute from a pointer to a pointer
--> tests/ui/transmute_ptr_to_ptr.rs:72:14
--> tests/ui/transmute_ptr_to_ptr.rs:79:14
|
LL | unsafe { transmute(v) }
| ^^^^^^^^^^^^
Expand All @@ -91,7 +91,7 @@ LL + unsafe { v as *const &() }
|

error: transmute from a pointer to a pointer
--> tests/ui/transmute_ptr_to_ptr.rs:87:28
--> tests/ui/transmute_ptr_to_ptr.rs:94:28
|
LL | let _: *const i8 = transmute(ptr);
| ^^^^^^^^^^^^^^
Expand All @@ -103,7 +103,7 @@ LL + let _: *const i8 = ptr as *const i8;
|

error: transmute from a pointer to a pointer
--> tests/ui/transmute_ptr_to_ptr.rs:95:28
--> tests/ui/transmute_ptr_to_ptr.rs:102:28
|
LL | let _: *const i8 = transmute(ptr);
| ^^^^^^^^^^^^^^
Expand All @@ -115,7 +115,7 @@ LL + let _: *const i8 = ptr.cast::<i8>();
|

error: transmute from a pointer to a pointer
--> tests/ui/transmute_ptr_to_ptr.rs:103:26
--> tests/ui/transmute_ptr_to_ptr.rs:110:26
|
LL | let _: *mut u8 = transmute(ptr);
| ^^^^^^^^^^^^^^
Expand All @@ -127,7 +127,7 @@ LL + let _: *mut u8 = ptr as *mut u8;
|

error: transmute from a pointer to a pointer
--> tests/ui/transmute_ptr_to_ptr.rs:105:28
--> tests/ui/transmute_ptr_to_ptr.rs:112:28
|
LL | let _: *const u8 = transmute(mut_ptr);
| ^^^^^^^^^^^^^^^^^^
Expand All @@ -139,7 +139,7 @@ LL + let _: *const u8 = mut_ptr as *const u8;
|

error: transmute from a pointer to a pointer
--> tests/ui/transmute_ptr_to_ptr.rs:113:26
--> tests/ui/transmute_ptr_to_ptr.rs:120:26
|
LL | let _: *mut u8 = transmute(ptr);
| ^^^^^^^^^^^^^^
Expand All @@ -151,7 +151,7 @@ LL + let _: *mut u8 = ptr.cast_mut();
|

error: transmute from a pointer to a pointer
--> tests/ui/transmute_ptr_to_ptr.rs:115:28
--> tests/ui/transmute_ptr_to_ptr.rs:122:28
|
LL | let _: *const u8 = transmute(mut_ptr);
| ^^^^^^^^^^^^^^^^^^
Expand All @@ -162,5 +162,29 @@ LL - let _: *const u8 = transmute(mut_ptr);
LL + let _: *const u8 = mut_ptr.cast_const();
|

error: aborting due to 16 previous errors
error: transmute from a reference to a reference
--> tests/ui/transmute_ptr_to_ptr.rs:129:9
|
LL | transmute::<&[u8], &mut [u8]>(bs)[4] = 42;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(&mut *(bs as *const [u8] as *mut [u8]))`

error: transmute from a reference to a reference
--> tests/ui/transmute_ptr_to_ptr.rs:131:17
|
LL | let _ = transmute::<&[u8], &mut [u8]>(bs).len();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(&mut *(bs as *const [u8] as *mut [u8]))`

error: transmute from a reference to a reference
--> tests/ui/transmute_ptr_to_ptr.rs:134:17
|
LL | let _ = transmute::<&[u8], &mut (u8, [u8])>(bs).0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(&mut *(bs as *const [u8] as *mut (u8, [u8])))`

error: transmute from a reference to a reference
--> tests/ui/transmute_ptr_to_ptr.rs:142:23
|
LL | let _ = S.foo(transmute::<&[u8], &mut [u8]>(bs));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(bs as *const [u8] as *mut [u8])`

error: aborting due to 20 previous errors