1 use clippy_utils
::diagnostics
::span_lint_and_sugg
;
2 use clippy_utils
::msrvs
::{self, Msrv}
;
3 use clippy_utils
::source
::snippet_with_applicability
;
4 use clippy_utils
::{match_def_path, paths}
;
5 use if_chain
::if_chain
;
6 use rustc_errors
::Applicability
;
7 use rustc_hir
::{def_id::DefId, Expr, ExprKind}
;
8 use rustc_lint
::LateContext
;
9 use rustc_middle
::ty
::{self, Ty}
;
11 use super::CAST_SLICE_FROM_RAW_PARTS
;
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
)
28 pub(super) fn check(cx
: &LateContext
<'_
>, expr
: &Expr
<'_
>, cast_expr
: &Expr
<'_
>, cast_to
: Ty
<'_
>, msrv
: &Msrv
) {
30 if msrv
.meets(msrvs
::PTR_SLICE_RAW_PARTS
);
31 if let ty
::RawPtr(ptrty
) = cast_to
.kind();
32 if let ty
::Slice(_
) = ptrty
.ty
.kind();
33 if let ExprKind
::Call(fun
, [ptr_arg
, len_arg
]) = cast_expr
.peel_blocks().kind
;
34 if let ExprKind
::Path(ref qpath
) = fun
.kind
;
35 if let Some(fun_def_id
) = cx
.qpath_res(qpath
, fun
.hir_id
).opt_def_id();
36 if let Some(rpk
) = raw_parts_kind(cx
, fun_def_id
);
38 let func
= match rpk
{
39 RawPartsKind
::Immutable
=> "from_raw_parts",
40 RawPartsKind
::Mutable
=> "from_raw_parts_mut"
43 let mut applicability
= Applicability
::MachineApplicable
;
44 let ptr
= snippet_with_applicability(cx
, ptr_arg
.span
, "ptr", &mut applicability
);
45 let len
= snippet_with_applicability(cx
, len_arg
.span
, "len", &mut applicability
);
48 CAST_SLICE_FROM_RAW_PARTS
,
50 &format
!("casting the result of `{func}` to {cast_to}"),
52 format
!("core::ptr::slice_{func}({ptr}, {len})"),