about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYusuke Tanaka <yusuktan@maguro.dev>2021-02-11 01:21:38 +0900
committerflip1995 <philipp.krones@embecosm.com>2021-03-02 10:40:24 +0100
commitc57a8260f22d4968f8c802ce92593a32e1e27f4c (patch)
treefab23487bccbceb6168a5d3db6b1b41e18ec82e0
parente7d2393d0182f9837897723e1541c0404bdcd55b (diff)
downloadrust-c57a8260f22d4968f8c802ce92593a32e1e27f4c.tar.gz
rust-c57a8260f22d4968f8c802ce92593a32e1e27f4c.zip
Move unsound_collection_transmute to its own module
-rw-r--r--clippy_lints/src/transmute/mod.rs35
-rw-r--r--clippy_lints/src/transmute/unsound_collection_transmute.rs49
2 files changed, 54 insertions, 30 deletions
diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs
index 3ba0872393d..8cb4f650057 100644
--- a/clippy_lints/src/transmute/mod.rs
+++ b/clippy_lints/src/transmute/mod.rs
@@ -6,6 +6,7 @@ mod transmute_int_to_float;
 mod transmute_ptr_to_ptr;
 mod transmute_ptr_to_ref;
 mod transmute_ref_to_ref;
+mod unsound_collection_transmute;
 mod useless_transmute;
 mod utils;
 mod wrong_transmute;
@@ -327,17 +328,6 @@ declare_lint_pass!(Transmute => [
     TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,
 ]);
 
-// used to check for UNSOUND_COLLECTION_TRANSMUTE
-static COLLECTIONS: &[&[&str]] = &[
-    &paths::VEC,
-    &paths::VEC_DEQUE,
-    &paths::BINARY_HEAP,
-    &paths::BTREESET,
-    &paths::BTREEMAP,
-    &paths::HASHSET,
-    &paths::HASHMAP,
-];
-
 impl<'tcx> LateLintPass<'tcx> for Transmute {
     #[allow(clippy::similar_names, clippy::too_many_lines)]
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
@@ -395,27 +385,12 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
                 if triggered {
                     return;
                 }
+                let triggered = unsound_collection_transmute::check(cx, e, from_ty, to_ty);
+                if triggered {
+                    return;
+                }
 
                 match (&from_ty.kind(), &to_ty.kind()) {
-                    (ty::Adt(from_adt, from_substs), ty::Adt(to_adt, to_substs)) => {
-                        if from_adt.did != to_adt.did ||
-                                !COLLECTIONS.iter().any(|path| match_def_path(cx, to_adt.did, path)) {
-                            return;
-                        }
-                        if from_substs.types().zip(to_substs.types())
-                                              .any(|(from_ty, to_ty)| is_layout_incompatible(cx, from_ty, to_ty)) {
-                            span_lint(
-                                cx,
-                                UNSOUND_COLLECTION_TRANSMUTE,
-                                e.span,
-                                &format!(
-                                    "transmute from `{}` to `{}` with mismatched layout is unsound",
-                                    from_ty,
-                                    to_ty
-                                )
-                            );
-                        }
-                    },
                     (_, _) if can_be_expressed_as_pointer_cast(cx, e, from_ty, to_ty) => span_lint_and_then(
                         cx,
                         TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,
diff --git a/clippy_lints/src/transmute/unsound_collection_transmute.rs b/clippy_lints/src/transmute/unsound_collection_transmute.rs
new file mode 100644
index 00000000000..3ce6bcd3ea0
--- /dev/null
+++ b/clippy_lints/src/transmute/unsound_collection_transmute.rs
@@ -0,0 +1,49 @@
+use super::utils::is_layout_incompatible;
+use super::UNSOUND_COLLECTION_TRANSMUTE;
+use crate::utils::{match_def_path, paths, span_lint};
+use rustc_hir::Expr;
+use rustc_lint::LateContext;
+use rustc_middle::ty;
+use rustc_middle::ty::Ty;
+
+// used to check for UNSOUND_COLLECTION_TRANSMUTE
+static COLLECTIONS: &[&[&str]] = &[
+    &paths::VEC,
+    &paths::VEC_DEQUE,
+    &paths::BINARY_HEAP,
+    &paths::BTREESET,
+    &paths::BTREEMAP,
+    &paths::HASHSET,
+    &paths::HASHMAP,
+];
+
+/// Checks for `unsound_collection_transmute` lint.
+/// Returns `true` if it's triggered, otherwise returns `false`.
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool {
+    match (&from_ty.kind(), &to_ty.kind()) {
+        (ty::Adt(from_adt, from_substs), ty::Adt(to_adt, to_substs)) => {
+            if from_adt.did != to_adt.did || !COLLECTIONS.iter().any(|path| match_def_path(cx, to_adt.did, path)) {
+                return false;
+            }
+            if from_substs
+                .types()
+                .zip(to_substs.types())
+                .any(|(from_ty, to_ty)| is_layout_incompatible(cx, from_ty, to_ty))
+            {
+                span_lint(
+                    cx,
+                    UNSOUND_COLLECTION_TRANSMUTE,
+                    e.span,
+                    &format!(
+                        "transmute from `{}` to `{}` with mismatched layout is unsound",
+                        from_ty, to_ty
+                    ),
+                );
+                true
+            } else {
+                false
+            }
+        },
+        _ => false,
+    }
+}