Skip to content

Commit e4f5090

Browse files
committed
fix: transmute_ptr_to_ptr wrongly unmangled macros
1 parent e4b3f01 commit e4f5090

File tree

4 files changed

+91
-58
lines changed

4 files changed

+91
-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 & 24 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_with_context;
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,49 +27,46 @@ pub(super) fn check<'tcx>(
2927

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

32-
let mut applicability = Applicability::MachineApplicable;
33-
let (snippet, _) = snippet_with_context(cx, arg.span, e.span.ctxt(), "..", &mut applicability);
34-
3530
span_lint_and_sugg(
3631
cx,
3732
TRANSMUTE_BYTES_TO_STR,
3833
e.span,
3934
format!("transmute from a `{from_ty}` to a `{to_ty}`"),
4035
"consider using",
4136
if const_context {
42-
format!("{top_crate}::str::from_utf8_unchecked{postfix}({snippet})")
37+
format!("{top_crate}::str::from_utf8_unchecked{postfix}({})", arg_sugg())
4338
} else {
44-
format!("{top_crate}::str::from_utf8{postfix}({snippet}).unwrap()")
39+
format!("{top_crate}::str::from_utf8{postfix}({}).unwrap()", arg_sugg())
4540
},
4641
Applicability::MaybeIncorrect,
4742
);
48-
triggered = true;
49-
} else if (cx.tcx.erase_and_anonymize_regions(from_ty) != cx.tcx.erase_and_anonymize_regions(to_ty))
50-
&& !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
5148
{
5249
span_lint_and_then(
5350
cx,
5451
TRANSMUTE_PTR_TO_PTR,
5552
e.span,
5653
"transmute from a reference to a reference",
5754
|diag| {
58-
if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) {
59-
let sugg_paren = arg
60-
.as_ty(Ty::new_ptr(cx.tcx, ty_from, from_mutbl))
61-
.as_ty(Ty::new_ptr(cx.tcx, ty_to, to_mutbl));
62-
let sugg = if to_mutbl == Mutability::Mut {
63-
sugg_paren.mut_addr_deref()
64-
} else {
65-
sugg_paren.addr_deref()
66-
};
67-
diag.span_suggestion(e.span, "try", sugg, Applicability::Unspecified);
68-
}
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);
6964
},
7065
);
7166

72-
triggered = true;
67+
return true;
7368
}
7469
}
7570

76-
triggered
71+
false
7772
}

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)