Skip to main content

rapx/analysis/api_dependency/
utils.rs

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