summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs
new file mode 100644
index 000000000..9409f4844
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs
@@ -0,0 +1,38 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_opt;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::LateContext;
+use rustc_middle::{
+ mir::Mutability,
+ ty::{self, Ty, TypeAndMut},
+};
+
+use super::AS_PTR_CAST_MUT;
+
+pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to: Ty<'_>) {
+ if let ty::RawPtr(ptrty @ TypeAndMut { mutbl: Mutability::Mut, .. }) = cast_to.kind()
+ && let ty::RawPtr(TypeAndMut { mutbl: Mutability::Not, .. }) =
+ cx.typeck_results().node_type(cast_expr.hir_id).kind()
+ && let ExprKind::MethodCall(method_name, receiver, [], _) = cast_expr.peel_blocks().kind
+ && method_name.ident.name == rustc_span::sym::as_ptr
+ && let Some(as_ptr_did) = cx.typeck_results().type_dependent_def_id(cast_expr.peel_blocks().hir_id)
+ && let as_ptr_sig = cx.tcx.fn_sig(as_ptr_did)
+ && let Some(first_param_ty) = as_ptr_sig.skip_binder().inputs().iter().next()
+ && let ty::Ref(_, _, Mutability::Not) = first_param_ty.kind()
+ && let Some(recv) = snippet_opt(cx, receiver.span)
+ {
+ // `as_mut_ptr` might not exist
+ let applicability = Applicability::MaybeIncorrect;
+
+ span_lint_and_sugg(
+ cx,
+ AS_PTR_CAST_MUT,
+ expr.span,
+ &format!("casting the result of `as_ptr` to *{ptrty}"),
+ "replace with",
+ format!("{recv}.as_mut_ptr()"),
+ applicability
+ );
+ }
+}