]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs
Move `{core,std}::stream::Stream` to `{core,std}::async_iter::AsyncIterator`.
[rust.git] / src / tools / clippy / clippy_lints / src / transmute / unsound_collection_transmute.rs
1 use super::utils::is_layout_incompatible;
2 use super::UNSOUND_COLLECTION_TRANSMUTE;
3 use clippy_utils::diagnostics::span_lint;
4 use clippy_utils::match_any_diagnostic_items;
5 use rustc_hir::Expr;
6 use rustc_lint::LateContext;
7 use rustc_middle::ty::{self, Ty};
8 use rustc_span::symbol::{sym, Symbol};
9
10 // used to check for UNSOUND_COLLECTION_TRANSMUTE
11 static COLLECTIONS: &[Symbol] = &[
12     sym::Vec,
13     sym::VecDeque,
14     sym::BinaryHeap,
15     sym::BTreeSet,
16     sym::BTreeMap,
17     sym::HashSet,
18     sym::HashMap,
19 ];
20
21 /// Checks for `unsound_collection_transmute` lint.
22 /// Returns `true` if it's triggered, otherwise returns `false`.
23 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool {
24     match (&from_ty.kind(), &to_ty.kind()) {
25         (ty::Adt(from_adt, from_substs), ty::Adt(to_adt, to_substs)) => {
26             if from_adt.did != to_adt.did || match_any_diagnostic_items(cx, to_adt.did, COLLECTIONS).is_none() {
27                 return false;
28             }
29             if from_substs
30                 .types()
31                 .zip(to_substs.types())
32                 .any(|(from_ty, to_ty)| is_layout_incompatible(cx, from_ty, to_ty))
33             {
34                 span_lint(
35                     cx,
36                     UNSOUND_COLLECTION_TRANSMUTE,
37                     e.span,
38                     &format!(
39                         "transmute from `{}` to `{}` with mismatched layout is unsound",
40                         from_ty, to_ty
41                     ),
42                 );
43                 true
44             } else {
45                 false
46             }
47         },
48         _ => false,
49     }
50 }