Skip to content

Commit c57a826

Browse files
magurotunaflip1995
authored andcommitted
Move unsound_collection_transmute to its own module
1 parent e7d2393 commit c57a826

File tree

2 files changed

+54
-30
lines changed

2 files changed

+54
-30
lines changed

clippy_lints/src/transmute/mod.rs

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ mod transmute_int_to_float;
66
mod transmute_ptr_to_ptr;
77
mod transmute_ptr_to_ref;
88
mod transmute_ref_to_ref;
9+
mod unsound_collection_transmute;
910
mod useless_transmute;
1011
mod utils;
1112
mod wrong_transmute;
@@ -327,17 +328,6 @@ declare_lint_pass!(Transmute => [
327328
TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,
328329
]);
329330

330-
// used to check for UNSOUND_COLLECTION_TRANSMUTE
331-
static COLLECTIONS: &[&[&str]] = &[
332-
&paths::VEC,
333-
&paths::VEC_DEQUE,
334-
&paths::BINARY_HEAP,
335-
&paths::BTREESET,
336-
&paths::BTREEMAP,
337-
&paths::HASHSET,
338-
&paths::HASHMAP,
339-
];
340-
341331
impl<'tcx> LateLintPass<'tcx> for Transmute {
342332
#[allow(clippy::similar_names, clippy::too_many_lines)]
343333
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
@@ -395,27 +385,12 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
395385
if triggered {
396386
return;
397387
}
388+
let triggered = unsound_collection_transmute::check(cx, e, from_ty, to_ty);
389+
if triggered {
390+
return;
391+
}
398392

399393
match (&from_ty.kind(), &to_ty.kind()) {
400-
(ty::Adt(from_adt, from_substs), ty::Adt(to_adt, to_substs)) => {
401-
if from_adt.did != to_adt.did ||
402-
!COLLECTIONS.iter().any(|path| match_def_path(cx, to_adt.did, path)) {
403-
return;
404-
}
405-
if from_substs.types().zip(to_substs.types())
406-
.any(|(from_ty, to_ty)| is_layout_incompatible(cx, from_ty, to_ty)) {
407-
span_lint(
408-
cx,
409-
UNSOUND_COLLECTION_TRANSMUTE,
410-
e.span,
411-
&format!(
412-
"transmute from `{}` to `{}` with mismatched layout is unsound",
413-
from_ty,
414-
to_ty
415-
)
416-
);
417-
}
418-
},
419394
(_, _) if can_be_expressed_as_pointer_cast(cx, e, from_ty, to_ty) => span_lint_and_then(
420395
cx,
421396
TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use super::utils::is_layout_incompatible;
2+
use super::UNSOUND_COLLECTION_TRANSMUTE;
3+
use crate::utils::{match_def_path, paths, span_lint};
4+
use rustc_hir::Expr;
5+
use rustc_lint::LateContext;
6+
use rustc_middle::ty;
7+
use rustc_middle::ty::Ty;
8+
9+
// used to check for UNSOUND_COLLECTION_TRANSMUTE
10+
static COLLECTIONS: &[&[&str]] = &[
11+
&paths::VEC,
12+
&paths::VEC_DEQUE,
13+
&paths::BINARY_HEAP,
14+
&paths::BTREESET,
15+
&paths::BTREEMAP,
16+
&paths::HASHSET,
17+
&paths::HASHMAP,
18+
];
19+
20+
/// Checks for `unsound_collection_transmute` lint.
21+
/// Returns `true` if it's triggered, otherwise returns `false`.
22+
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool {
23+
match (&from_ty.kind(), &to_ty.kind()) {
24+
(ty::Adt(from_adt, from_substs), ty::Adt(to_adt, to_substs)) => {
25+
if from_adt.did != to_adt.did || !COLLECTIONS.iter().any(|path| match_def_path(cx, to_adt.did, path)) {
26+
return false;
27+
}
28+
if from_substs
29+
.types()
30+
.zip(to_substs.types())
31+
.any(|(from_ty, to_ty)| is_layout_incompatible(cx, from_ty, to_ty))
32+
{
33+
span_lint(
34+
cx,
35+
UNSOUND_COLLECTION_TRANSMUTE,
36+
e.span,
37+
&format!(
38+
"transmute from `{}` to `{}` with mismatched layout is unsound",
39+
from_ty, to_ty
40+
),
41+
);
42+
true
43+
} else {
44+
false
45+
}
46+
},
47+
_ => false,
48+
}
49+
}

0 commit comments

Comments
 (0)