Skip to content

Commit 1de71c8

Browse files
committed
ptr_cast_constness: avoid suggesting unresolvable method call
1 parent 798f754 commit 1de71c8

File tree

4 files changed

+30
-3
lines changed

4 files changed

+30
-3
lines changed

clippy_lints/src/casts/ptr_cast_constness.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use clippy_utils::source::snippet_with_applicability;
44
use clippy_utils::sugg::Sugg;
55
use clippy_utils::{std_or_core, sym};
66
use rustc_errors::Applicability;
7-
use rustc_hir::{Expr, ExprKind, QPath};
7+
use rustc_hir::{self as hir, Expr, ExprKind, QPath};
88
use rustc_lint::LateContext;
99
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
1010

@@ -51,7 +51,16 @@ pub(super) fn check<'tcx>(
5151

5252
if msrv.meets(cx, msrvs::POINTER_CAST_CONSTNESS) {
5353
let mut app = Applicability::MachineApplicable;
54-
let sugg = Sugg::hir_with_context(cx, cast_from_expr, expr.span.ctxt(), "_", &mut app);
54+
let sugg = if let ExprKind::Cast(nested_from, nested_hir_ty) = cast_from_expr.kind
55+
&& let hir::TyKind::Ptr(ptr_ty) = nested_hir_ty.kind
56+
&& let hir::TyKind::Infer(()) = ptr_ty.ty.kind
57+
{
58+
// `(foo as *const _).cast_mut()` fails method name resolution
59+
// avoid this by `as`-ing the full type
60+
Sugg::hir_with_context(cx, nested_from, expr.span.ctxt(), "_", &mut app).as_ty(cast_from)
61+
} else {
62+
Sugg::hir_with_context(cx, cast_from_expr, expr.span.ctxt(), "_", &mut app)
63+
};
5564
let constness = to_mutbl.ptr_str();
5665

5766
span_lint_and_sugg(

tests/ui/ptr_cast_constness.fixed

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,9 @@ fn issue14621() {
106106
let _ = std::ptr::addr_of_mut!(local).cast_const();
107107
//~^ ptr_cast_constness
108108
}
109+
110+
fn issue11317() {
111+
let r = &0_u32;
112+
let _ptr: *mut u32 = (r as *const u32).cast_mut();
113+
//~^ ptr_cast_constness
114+
}

tests/ui/ptr_cast_constness.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,9 @@ fn issue14621() {
106106
let _ = std::ptr::addr_of_mut!(local) as *const _;
107107
//~^ ptr_cast_constness
108108
}
109+
110+
fn issue11317() {
111+
let r = &0_u32;
112+
let _ptr: *mut u32 = r as *const _ as *mut _;
113+
//~^ ptr_cast_constness
114+
}

tests/ui/ptr_cast_constness.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,11 @@ error: `as` casting between raw pointers while changing only its constness
8989
LL | let _ = std::ptr::addr_of_mut!(local) as *const _;
9090
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `std::ptr::addr_of_mut!(local).cast_const()`
9191

92-
error: aborting due to 14 previous errors
92+
error: `as` casting between raw pointers while changing only its constness
93+
--> tests/ui/ptr_cast_constness.rs:112:26
94+
|
95+
LL | let _ptr: *mut u32 = r as *const _ as *mut _;
96+
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `(r as *const u32).cast_mut()`
97+
98+
error: aborting due to 15 previous errors
9399

0 commit comments

Comments
 (0)