Move unsound_collection_transmute to its own module

This commit is contained in:
Yusuke Tanaka 2021-02-11 01:21:38 +09:00 committed by flip1995
parent e7d2393d01
commit c57a8260f2
No known key found for this signature in database
GPG key ID: 1CA0DF2AF59D68A5
2 changed files with 54 additions and 30 deletions

View file

@ -6,6 +6,7 @@ mod transmute_int_to_float;
mod transmute_ptr_to_ptr; mod transmute_ptr_to_ptr;
mod transmute_ptr_to_ref; mod transmute_ptr_to_ref;
mod transmute_ref_to_ref; mod transmute_ref_to_ref;
mod unsound_collection_transmute;
mod useless_transmute; mod useless_transmute;
mod utils; mod utils;
mod wrong_transmute; mod wrong_transmute;
@ -327,17 +328,6 @@ declare_lint_pass!(Transmute => [
TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS, 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 { impl<'tcx> LateLintPass<'tcx> for Transmute {
#[allow(clippy::similar_names, clippy::too_many_lines)] #[allow(clippy::similar_names, clippy::too_many_lines)]
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
@ -395,27 +385,12 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
if triggered { if triggered {
return; return;
} }
let triggered = unsound_collection_transmute::check(cx, e, from_ty, to_ty);
if triggered {
return;
}
match (&from_ty.kind(), &to_ty.kind()) { 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( (_, _) if can_be_expressed_as_pointer_cast(cx, e, from_ty, to_ty) => span_lint_and_then(
cx, cx,
TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS, TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,

View file

@ -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,
}
}