rapx/analysis/safedrop/
types.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
use super::corner_handle::is_corner_adt;
use rustc_middle::ty;
use rustc_middle::ty::{Ty, TyCtxt};

#[derive(PartialEq, Debug, Copy, Clone)]
pub enum TyKind {
    Adt,
    RawPtr,
    Tuple,
    CornerCase,
    Ref,
}

pub fn kind<'tcx>(current_ty: Ty<'tcx>) -> TyKind {
    match current_ty.kind() {
        ty::RawPtr(..) => TyKind::RawPtr,
        ty::Ref(..) => TyKind::Ref,
        ty::Tuple(..) => TyKind::Tuple,
        ty::Adt(ref adt_def, _) => {
            if is_corner_adt(format!("{:?}", adt_def)) {
                return TyKind::CornerCase;
            } else {
                return TyKind::Adt;
            }
        }
        _ => TyKind::Adt,
    }
}

pub fn is_not_drop<'tcx>(tcx: TyCtxt<'tcx>, current_ty: Ty<'tcx>) -> bool {
    match current_ty.kind() {
        ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) => true,
        ty::Array(ref tys, _) => is_not_drop(tcx, *tys),
        ty::Adt(ref adtdef, ref substs) => {
            for field in adtdef.all_fields() {
                if !is_not_drop(tcx, field.ty(tcx, substs)) {
                    return false;
                }
            }
            true
        }
        ty::Tuple(ref tuple_fields) => {
            for tys in tuple_fields.iter() {
                if !is_not_drop(tcx, tys) {
                    return false;
                }
            }
            true
        }
        _ => false,
    }
}