Skip to content

Commit 45168a7

Browse files
Fix wrongly unmangled macros for transmute_ptr_to_ptr and transmute_bytes_to_str (#16105)
Closes #16104 changelog: [`transmute_ptr_to_ptr`] fix wrongly unmangled macros [`transmute_bytes_to_str`] fix wrongly unmangled macros
2 parents 37b485b + e4f5090 commit 45168a7

File tree

6 files changed

+111
-58
lines changed

6 files changed

+111
-58
lines changed

clippy_lints/src/transmute/transmute_ptr_to_ptr.rs

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ pub(super) fn check<'tcx>(
1717
arg: &'tcx Expr<'_>,
1818
msrv: Msrv,
1919
) -> bool {
20+
let mut applicability = Applicability::MachineApplicable;
21+
let arg_sugg = sugg::Sugg::hir_with_context(cx, arg, e.span.ctxt(), "..", &mut applicability);
2022
match (from_ty.kind(), to_ty.kind()) {
2123
(ty::RawPtr(from_pointee_ty, from_mutbl), ty::RawPtr(to_pointee_ty, to_mutbl)) => {
2224
span_lint_and_then(
@@ -25,40 +27,38 @@ pub(super) fn check<'tcx>(
2527
e.span,
2628
"transmute from a pointer to a pointer",
2729
|diag| {
28-
if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) {
29-
if from_mutbl == to_mutbl
30-
&& to_pointee_ty.is_sized(cx.tcx, cx.typing_env())
31-
&& msrv.meets(cx, msrvs::POINTER_CAST)
32-
{
33-
diag.span_suggestion_verbose(
34-
e.span,
35-
"use `pointer::cast` instead",
36-
format!("{}.cast::<{to_pointee_ty}>()", arg.maybe_paren()),
37-
Applicability::MaybeIncorrect,
38-
);
39-
} else if from_pointee_ty == to_pointee_ty
40-
&& let Some(method) = match (from_mutbl, to_mutbl) {
41-
(ty::Mutability::Not, ty::Mutability::Mut) => Some("cast_mut"),
42-
(ty::Mutability::Mut, ty::Mutability::Not) => Some("cast_const"),
43-
_ => None,
44-
}
45-
&& !from_pointee_ty.has_erased_regions()
46-
&& msrv.meets(cx, msrvs::POINTER_CAST_CONSTNESS)
47-
{
48-
diag.span_suggestion_verbose(
49-
e.span,
50-
format!("use `pointer::{method}` instead"),
51-
format!("{}.{method}()", arg.maybe_paren()),
52-
Applicability::MaybeIncorrect,
53-
);
54-
} else {
55-
diag.span_suggestion_verbose(
56-
e.span,
57-
"use an `as` cast instead",
58-
arg.as_ty(to_ty),
59-
Applicability::MaybeIncorrect,
60-
);
30+
if from_mutbl == to_mutbl
31+
&& to_pointee_ty.is_sized(cx.tcx, cx.typing_env())
32+
&& msrv.meets(cx, msrvs::POINTER_CAST)
33+
{
34+
diag.span_suggestion_verbose(
35+
e.span,
36+
"use `pointer::cast` instead",
37+
format!("{}.cast::<{to_pointee_ty}>()", arg_sugg.maybe_paren()),
38+
Applicability::MaybeIncorrect,
39+
);
40+
} else if from_pointee_ty == to_pointee_ty
41+
&& let Some(method) = match (from_mutbl, to_mutbl) {
42+
(ty::Mutability::Not, ty::Mutability::Mut) => Some("cast_mut"),
43+
(ty::Mutability::Mut, ty::Mutability::Not) => Some("cast_const"),
44+
_ => None,
6145
}
46+
&& !from_pointee_ty.has_erased_regions()
47+
&& msrv.meets(cx, msrvs::POINTER_CAST_CONSTNESS)
48+
{
49+
diag.span_suggestion_verbose(
50+
e.span,
51+
format!("use `pointer::{method}` instead"),
52+
format!("{}.{method}()", arg_sugg.maybe_paren()),
53+
Applicability::MaybeIncorrect,
54+
);
55+
} else {
56+
diag.span_suggestion_verbose(
57+
e.span,
58+
"use an `as` cast instead",
59+
arg_sugg.as_ty(to_ty),
60+
Applicability::MaybeIncorrect,
61+
);
6262
}
6363
},
6464
);
Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use super::{TRANSMUTE_BYTES_TO_STR, TRANSMUTE_PTR_TO_PTR};
22
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
3-
use clippy_utils::source::snippet;
43
use clippy_utils::{std_or_core, sugg};
54
use rustc_errors::Applicability;
65
use rustc_hir::{Expr, Mutability};
@@ -17,8 +16,7 @@ pub(super) fn check<'tcx>(
1716
arg: &'tcx Expr<'_>,
1817
const_context: bool,
1918
) -> bool {
20-
let mut triggered = false;
21-
19+
let arg_sugg = || sugg::Sugg::hir_with_context(cx, arg, e.span.ctxt(), "..", &mut Applicability::Unspecified);
2220
if let (ty::Ref(_, ty_from, from_mutbl), ty::Ref(_, ty_to, to_mutbl)) = (*from_ty.kind(), *to_ty.kind()) {
2321
if let ty::Slice(slice_ty) = *ty_from.kind()
2422
&& ty_to.is_str()
@@ -29,48 +27,46 @@ pub(super) fn check<'tcx>(
2927

3028
let postfix = if from_mutbl == Mutability::Mut { "_mut" } else { "" };
3129

32-
let snippet = snippet(cx, arg.span, "..");
33-
3430
span_lint_and_sugg(
3531
cx,
3632
TRANSMUTE_BYTES_TO_STR,
3733
e.span,
3834
format!("transmute from a `{from_ty}` to a `{to_ty}`"),
3935
"consider using",
4036
if const_context {
41-
format!("{top_crate}::str::from_utf8_unchecked{postfix}({snippet})")
37+
format!("{top_crate}::str::from_utf8_unchecked{postfix}({})", arg_sugg())
4238
} else {
43-
format!("{top_crate}::str::from_utf8{postfix}({snippet}).unwrap()")
39+
format!("{top_crate}::str::from_utf8{postfix}({}).unwrap()", arg_sugg())
4440
},
4541
Applicability::MaybeIncorrect,
4642
);
47-
triggered = true;
48-
} else if (cx.tcx.erase_and_anonymize_regions(from_ty) != cx.tcx.erase_and_anonymize_regions(to_ty))
49-
&& !const_context
43+
44+
return true;
45+
}
46+
47+
if (cx.tcx.erase_and_anonymize_regions(from_ty) != cx.tcx.erase_and_anonymize_regions(to_ty)) && !const_context
5048
{
5149
span_lint_and_then(
5250
cx,
5351
TRANSMUTE_PTR_TO_PTR,
5452
e.span,
5553
"transmute from a reference to a reference",
5654
|diag| {
57-
if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) {
58-
let sugg_paren = arg
59-
.as_ty(Ty::new_ptr(cx.tcx, ty_from, from_mutbl))
60-
.as_ty(Ty::new_ptr(cx.tcx, ty_to, to_mutbl));
61-
let sugg = if to_mutbl == Mutability::Mut {
62-
sugg_paren.mut_addr_deref()
63-
} else {
64-
sugg_paren.addr_deref()
65-
};
66-
diag.span_suggestion(e.span, "try", sugg, Applicability::Unspecified);
67-
}
55+
let sugg_paren = arg_sugg()
56+
.as_ty(Ty::new_ptr(cx.tcx, ty_from, from_mutbl))
57+
.as_ty(Ty::new_ptr(cx.tcx, ty_to, to_mutbl));
58+
let sugg = if to_mutbl == Mutability::Mut {
59+
sugg_paren.mut_addr_deref()
60+
} else {
61+
sugg_paren.addr_deref()
62+
};
63+
diag.span_suggestion(e.span, "try", sugg, Applicability::Unspecified);
6864
},
6965
);
7066

71-
triggered = true;
67+
return true;
7268
}
7369
}
7470

75-
triggered
71+
false
7672
}

tests/ui/transmute.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,17 @@ fn bytes_to_str(mb: &mut [u8]) {
128128
//~^ transmute_bytes_to_str
129129
}
130130

131+
fn issue16104() {
132+
let b = vec![1_u8, 2_u8];
133+
macro_rules! take_ref {
134+
($x:expr) => {
135+
$x.as_slice()
136+
};
137+
}
138+
unsafe {
139+
let _: &str = std::mem::transmute(take_ref!(b));
140+
//~^ transmute_bytes_to_str
141+
}
142+
}
143+
131144
fn main() {}

tests/ui/transmute.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,5 +106,11 @@ error: transmute from a `&[u8]` to a `&str`
106106
LL | const _: &str = unsafe { std::mem::transmute(B) };
107107
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)`
108108

109-
error: aborting due to 16 previous errors
109+
error: transmute from a `&[u8]` to a `&str`
110+
--> tests/ui/transmute.rs:139:23
111+
|
112+
LL | let _: &str = std::mem::transmute(take_ref!(b));
113+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(take_ref!(b)).unwrap()`
114+
115+
error: aborting due to 17 previous errors
110116

tests/ui/transmute_ref_to_ref.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,23 @@ fn main() {
1818
//~^ transmute_ptr_to_ptr
1919
}
2020
}
21+
22+
fn issue16104(make_ptr: fn() -> *const u32) {
23+
macro_rules! call {
24+
($x:expr) => {
25+
$x()
26+
};
27+
}
28+
macro_rules! take_ref {
29+
($x:expr) => {
30+
&$x
31+
};
32+
}
33+
34+
unsafe {
35+
let _: *const f32 = std::mem::transmute(call!(make_ptr));
36+
//~^ transmute_ptr_to_ptr
37+
let _: &f32 = std::mem::transmute(take_ref!(1u32));
38+
//~^ transmute_ptr_to_ptr
39+
}
40+
}

tests/ui/transmute_ref_to_ref.stderr

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,23 @@ error: transmute from a reference to a reference
2222
LL | let alt_slice: &[u32] = unsafe { std::mem::transmute(bytes) };
2323
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(bytes as *const [u8] as *const [u32])`
2424

25-
error: aborting due to 3 previous errors
25+
error: transmute from a pointer to a pointer
26+
--> tests/ui/transmute_ref_to_ref.rs:35:29
27+
|
28+
LL | let _: *const f32 = std::mem::transmute(call!(make_ptr));
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
30+
|
31+
help: use `pointer::cast` instead
32+
|
33+
LL - let _: *const f32 = std::mem::transmute(call!(make_ptr));
34+
LL + let _: *const f32 = call!(make_ptr).cast::<f32>();
35+
|
36+
37+
error: transmute from a reference to a reference
38+
--> tests/ui/transmute_ref_to_ref.rs:37:23
39+
|
40+
LL | let _: &f32 = std::mem::transmute(take_ref!(1u32));
41+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(take_ref!(1u32) as *const u32 as *const f32)`
42+
43+
error: aborting due to 5 previous errors
2644

0 commit comments

Comments
 (0)