]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs
Rollup merge of #85760 - ChrisDenton:path-doc-platform-specific, r=m-ou-se
[rust.git] / src / tools / clippy / clippy_lints / src / transmute / useless_transmute.rs
1 use super::USELESS_TRANSMUTE;
2 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
3 use clippy_utils::sugg;
4 use rustc_errors::Applicability;
5 use rustc_hir::Expr;
6 use rustc_lint::LateContext;
7 use rustc_middle::ty::{self, Ty};
8
9 /// Checks for `useless_transmute` lint.
10 /// Returns `true` if it's triggered, otherwise returns `false`.
11 pub(super) fn check<'tcx>(
12     cx: &LateContext<'tcx>,
13     e: &'tcx Expr<'_>,
14     from_ty: Ty<'tcx>,
15     to_ty: Ty<'tcx>,
16     args: &'tcx [Expr<'_>],
17 ) -> bool {
18     match (&from_ty.kind(), &to_ty.kind()) {
19         _ if from_ty == to_ty => {
20             span_lint(
21                 cx,
22                 USELESS_TRANSMUTE,
23                 e.span,
24                 &format!("transmute from a type (`{}`) to itself", from_ty),
25             );
26             true
27         },
28         (ty::Ref(_, rty, rty_mutbl), ty::RawPtr(ptr_ty)) => {
29             span_lint_and_then(
30                 cx,
31                 USELESS_TRANSMUTE,
32                 e.span,
33                 "transmute from a reference to a pointer",
34                 |diag| {
35                     if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) {
36                         let rty_and_mut = ty::TypeAndMut {
37                             ty: rty,
38                             mutbl: *rty_mutbl,
39                         };
40
41                         let sugg = if *ptr_ty == rty_and_mut {
42                             arg.as_ty(to_ty)
43                         } else {
44                             arg.as_ty(cx.tcx.mk_ptr(rty_and_mut)).as_ty(to_ty)
45                         };
46
47                         diag.span_suggestion(e.span, "try", sugg.to_string(), Applicability::Unspecified);
48                     }
49                 },
50             );
51             true
52         },
53         (ty::Int(_) | ty::Uint(_), ty::RawPtr(_)) => {
54             span_lint_and_then(
55                 cx,
56                 USELESS_TRANSMUTE,
57                 e.span,
58                 "transmute from an integer to a pointer",
59                 |diag| {
60                     if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) {
61                         diag.span_suggestion(
62                             e.span,
63                             "try",
64                             arg.as_ty(&to_ty.to_string()).to_string(),
65                             Applicability::Unspecified,
66                         );
67                     }
68                 },
69             );
70             true
71         },
72         _ => false,
73     }
74 }