rapx/analysis/api_dependency/
utils.rs

1#![allow(warnings, unused)]
2use super::fuzzable;
3use rustc_hir::LangItem;
4use rustc_hir::def_id::DefId;
5use rustc_middle::ty::{self, FnSig, GenericArgsRef, Ty, TyCtxt, TyKind};
6use rustc_span::sym;
7
8pub fn is_def_id_public(fn_def_id: impl Into<DefId>, tcx: TyCtxt<'_>) -> bool {
9    let fn_def_id: DefId = fn_def_id.into();
10    let local_id = fn_def_id.expect_local();
11    rap_trace!(
12        "vis: {:?} (path: {}) => {:?}",
13        fn_def_id,
14        tcx.def_path_str(fn_def_id),
15        tcx.effective_visibilities(()).effective_vis(local_id)
16    );
17
18    tcx.effective_visibilities(()).is_directly_public(local_id)
19        || tcx.effective_visibilities(()).is_exported(local_id)
20}
21
22pub fn is_fuzzable_ty<'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
23    rap_trace!("check fuzzable ty: {}.", ty);
24    let is_fuzzable = fuzzable::is_fuzzable_ty(ty, tcx, 0);
25    rap_trace!("is_fuzzable({}) = {}.", ty, is_fuzzable);
26    is_fuzzable
27}
28
29pub fn is_fuzzable_api<'tcx>(fn_did: DefId, args: GenericArgsRef<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
30    let fn_sig = fn_sig_with_generic_args(fn_did, args, tcx);
31    fn_sig
32        .inputs()
33        .iter()
34        .copied()
35        .all(|ty| is_fuzzable_ty(ty, tcx))
36}
37
38pub fn fn_sig_with_generic_args<'tcx>(
39    fn_did: DefId,
40    args: &[ty::GenericArg<'tcx>],
41    tcx: TyCtxt<'tcx>,
42) -> FnSig<'tcx> {
43    let early_fn_sig = tcx.fn_sig(fn_did);
44    let binder_fn_sig = early_fn_sig.instantiate(tcx, args);
45    #[cfg(rapx_rustc_ge_198)]
46    let binder_fn_sig = binder_fn_sig.skip_norm_wip();
47    let result = tcx.liberate_late_bound_regions(fn_did, binder_fn_sig);
48    result
49}
50
51pub fn fn_requires_monomorphization<'tcx>(fn_did: DefId, tcx: TyCtxt<'_>) -> bool {
52    tcx.generics_of(fn_did).requires_monomorphization(tcx)
53}
54
55pub fn is_ty_eq<'tcx>(ty1: Ty<'tcx>, ty2: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
56    let ty1 = tcx.erase_and_anonymize_regions(ty1);
57    let ty2 = tcx.erase_and_anonymize_regions(ty2);
58    return ty1 == ty2;
59}
60
61pub fn ty_complexity<'tcx>(ty: Ty<'tcx>) -> usize {
62    match ty.kind() {
63        // Reference, Array, Slice
64        TyKind::Ref(_, inner_ty, _) | TyKind::Array(inner_ty, _) | TyKind::Slice(inner_ty) => {
65            ty_complexity(*inner_ty) + 1
66        }
67
68        // Tuple
69        TyKind::Tuple(tys) => tys.iter().fold(0, |ans, ty| ans.max(ty_complexity(ty))) + 1,
70
71        // ADT
72        TyKind::Adt(_, args) => {
73            args.iter().fold(0, |ans, arg| {
74                if let Some(ty) = arg.as_type() {
75                    ans.max(ty_complexity(ty))
76                } else {
77                    ans
78                }
79            }) + 1
80        }
81
82        // the depth of other primitive type default to 1
83        _ => 1,
84    }
85}
86
87pub fn is_ty_unstable<'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
88    ty == tcx.types.f16
89}