]>
Commit | Line | Data |
---|---|---|
f20569fa | 1 | use super::USELESS_TRANSMUTE; |
cdc7bbd5 XL |
2 | use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; |
3 | use clippy_utils::sugg; | |
f20569fa XL |
4 | use rustc_errors::Applicability; |
5 | use rustc_hir::Expr; | |
6 | use rustc_lint::LateContext; | |
9ffffee4 | 7 | use rustc_middle::ty::{self, Ty, TypeVisitableExt}; |
f20569fa XL |
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>, | |
5099ac24 | 16 | arg: &'tcx Expr<'_>, |
f20569fa XL |
17 | ) -> bool { |
18 | match (&from_ty.kind(), &to_ty.kind()) { | |
923072b8 | 19 | _ if from_ty == to_ty && !from_ty.has_erased_regions() => { |
f20569fa XL |
20 | span_lint( |
21 | cx, | |
22 | USELESS_TRANSMUTE, | |
23 | e.span, | |
2b03887a | 24 | &format!("transmute from a type (`{from_ty}`) to itself"), |
f20569fa XL |
25 | ); |
26 | true | |
27 | }, | |
28 | (ty::Ref(_, rty, rty_mutbl), ty::RawPtr(ptr_ty)) => { | |
923072b8 FG |
29 | // No way to give the correct suggestion here. Avoid linting for now. |
30 | if !rty.has_erased_regions() { | |
31 | span_lint_and_then( | |
32 | cx, | |
33 | USELESS_TRANSMUTE, | |
34 | e.span, | |
35 | "transmute from a reference to a pointer", | |
36 | |diag| { | |
37 | if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) { | |
38 | let rty_and_mut = ty::TypeAndMut { | |
39 | ty: *rty, | |
40 | mutbl: *rty_mutbl, | |
41 | }; | |
f20569fa | 42 | |
923072b8 FG |
43 | let sugg = if *ptr_ty == rty_and_mut { |
44 | arg.as_ty(to_ty) | |
45 | } else { | |
46 | arg.as_ty(cx.tcx.mk_ptr(rty_and_mut)).as_ty(to_ty) | |
47 | }; | |
f20569fa | 48 | |
923072b8 FG |
49 | diag.span_suggestion(e.span, "try", sugg, Applicability::Unspecified); |
50 | } | |
51 | }, | |
52 | ); | |
53 | } | |
f20569fa XL |
54 | true |
55 | }, | |
56 | (ty::Int(_) | ty::Uint(_), ty::RawPtr(_)) => { | |
57 | span_lint_and_then( | |
58 | cx, | |
59 | USELESS_TRANSMUTE, | |
60 | e.span, | |
61 | "transmute from an integer to a pointer", | |
62 | |diag| { | |
5099ac24 | 63 | if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) { |
9c376795 | 64 | diag.span_suggestion(e.span, "try", arg.as_ty(to_ty.to_string()), Applicability::Unspecified); |
f20569fa XL |
65 | } |
66 | }, | |
67 | ); | |
68 | true | |
69 | }, | |
70 | _ => false, | |
71 | } | |
72 | } |