]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
Rollup merge of #102854 - semarie:openbsd-immutablestack, r=m-ou-se
[rust.git] / src / tools / clippy / clippy_lints / src / casts / cast_slice_from_raw_parts.rs
1 use clippy_utils::diagnostics::span_lint_and_sugg;
2 use clippy_utils::source::snippet_with_applicability;
3 use clippy_utils::{match_def_path, meets_msrv, msrvs, paths};
4 use if_chain::if_chain;
5 use rustc_errors::Applicability;
6 use rustc_hir::{def_id::DefId, Expr, ExprKind};
7 use rustc_lint::LateContext;
8 use rustc_middle::ty::{self, Ty};
9 use rustc_semver::RustcVersion;
10
11 use super::CAST_SLICE_FROM_RAW_PARTS;
12
13 enum RawPartsKind {
14     Immutable,
15     Mutable,
16 }
17
18 fn raw_parts_kind(cx: &LateContext<'_>, did: DefId) -> Option<RawPartsKind> {
19     if match_def_path(cx, did, &paths::SLICE_FROM_RAW_PARTS) {
20         Some(RawPartsKind::Immutable)
21     } else if match_def_path(cx, did, &paths::SLICE_FROM_RAW_PARTS_MUT) {
22         Some(RawPartsKind::Mutable)
23     } else {
24         None
25     }
26 }
27
28 pub(super) fn check(
29     cx: &LateContext<'_>,
30     expr: &Expr<'_>,
31     cast_expr: &Expr<'_>,
32     cast_to: Ty<'_>,
33     msrv: Option<RustcVersion>,
34 ) {
35     if_chain! {
36         if meets_msrv(msrv, msrvs::PTR_SLICE_RAW_PARTS);
37         if let ty::RawPtr(ptrty) = cast_to.kind();
38         if let ty::Slice(_) = ptrty.ty.kind();
39         if let ExprKind::Call(fun, [ptr_arg, len_arg]) = cast_expr.peel_blocks().kind;
40         if let ExprKind::Path(ref qpath) = fun.kind;
41         if let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id();
42         if let Some(rpk) = raw_parts_kind(cx, fun_def_id);
43         then {
44             let func = match rpk {
45                 RawPartsKind::Immutable => "from_raw_parts",
46                 RawPartsKind::Mutable => "from_raw_parts_mut"
47             };
48             let span = expr.span;
49             let mut applicability = Applicability::MachineApplicable;
50             let ptr = snippet_with_applicability(cx, ptr_arg.span, "ptr", &mut applicability);
51             let len = snippet_with_applicability(cx, len_arg.span, "len", &mut applicability);
52             span_lint_and_sugg(
53                 cx,
54                 CAST_SLICE_FROM_RAW_PARTS,
55                 span,
56                 &format!("casting the result of `{func}` to {cast_to}"),
57                 "replace with",
58                 format!("core::ptr::slice_{func}({ptr}, {len})"),
59                 applicability
60             );
61         }
62     }
63 }