rapx/analysis/core/api_dependency/
utils.rs1#![allow(warnings, unused)]
2
3use rustc_hir::LangItem;
4use rustc_hir::def_id::DefId;
5use rustc_middle::ty::{self, FnSig, Ty, TyCtxt, TyKind};
6use rustc_span::sym;
7
8fn is_fuzzable_std_ty<'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
9 match ty.kind() {
10 ty::Adt(def, _) => {
11 tcx.is_lang_item(def.did(), LangItem::String)
12 || tcx.is_diagnostic_item(sym::Vec, def.did())
13 || tcx.is_diagnostic_item(sym::Arc, def.did())
14 }
15 _ => false,
16 }
17}
18
19pub fn is_fuzzable_ty<'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
20 if is_fuzzable_std_ty(ty, tcx) {
21 return true;
22 }
23
24 match ty.kind() {
25 TyKind::Bool
27 | TyKind::Char
28 | TyKind::Int(_)
29 | TyKind::Uint(_)
30 | TyKind::Float(_)
31 | TyKind::Str => true,
32
33 TyKind::Infer(
35 ty::InferTy::IntVar(_)
36 | ty::InferTy::FreshIntTy(_)
37 | ty::InferTy::FloatVar(_)
38 | ty::InferTy::FreshFloatTy(_),
39 ) => true,
40
41 TyKind::Ref(_, inner_ty, _) | TyKind::Array(inner_ty, _) | TyKind::Slice(inner_ty) => {
43 is_fuzzable_ty(inner_ty.peel_refs(), tcx)
44 }
45
46 TyKind::Tuple(tys) => tys
48 .iter()
49 .all(|inner_ty| is_fuzzable_ty(inner_ty.peel_refs(), tcx)),
50
51 TyKind::Adt(adt_def, substs) => {
53 if adt_def.variant_list_has_applicable_non_exhaustive() {
54 return false;
55 }
56 if adt_def.is_struct() {
57 adt_def.all_fields().all(|field| {
59 field.vis.is_public() && is_fuzzable_ty(field.ty(tcx, substs).peel_refs(), tcx)
61 })
62 } else if adt_def.is_enum() {
63 adt_def.variants().iter().all(|variant| {
64 variant
65 .fields
66 .iter()
67 .all(|field| is_fuzzable_ty(field.ty(tcx, substs).peel_refs(), tcx))
68 })
69 } else {
70 false }
72 }
73
74 _ => false,
76 }
77}
78
79pub fn fn_sig_without_binders<'tcx>(fn_did: DefId, tcx: TyCtxt<'tcx>) -> FnSig<'tcx> {
80 let early_fn_sig = tcx.fn_sig(fn_did);
81 let binder_fn_sig = early_fn_sig.instantiate_identity();
82 tcx.liberate_late_bound_regions(fn_did, binder_fn_sig)
83}
84
85pub fn fn_sig_with_generic_args<'tcx>(
86 fn_did: DefId,
87 args: &[ty::GenericArg<'tcx>],
88 tcx: TyCtxt<'tcx>,
89) -> FnSig<'tcx> {
90 let early_fn_sig = tcx.fn_sig(fn_did);
91 let binder_fn_sig = early_fn_sig.instantiate(tcx, args);
92 tcx.liberate_late_bound_regions(fn_did, binder_fn_sig)
93}
94
95pub fn fn_requires_monomorphization<'tcx>(fn_did: DefId, tcx: TyCtxt<'_>) -> bool {
96 tcx.generics_of(fn_did).requires_monomorphization(tcx)
97}
98
99pub fn is_ty_eq<'tcx>(ty1: Ty<'tcx>, ty2: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
100 let ty1 = tcx.erase_and_anonymize_regions(ty1);
101 let ty2 = tcx.erase_and_anonymize_regions(ty2);
102 return ty1 == ty2;
103}
104
105pub fn ty_complexity<'tcx>(ty: Ty<'tcx>) -> usize {
106 match ty.kind() {
107 TyKind::Ref(_, inner_ty, _) | TyKind::Array(inner_ty, _) | TyKind::Slice(inner_ty) => {
109 ty_complexity(*inner_ty) + 1
110 }
111
112 TyKind::Tuple(tys) => tys.iter().fold(0, |ans, ty| ans.max(ty_complexity(ty))) + 1,
114
115 TyKind::Adt(_, args) => {
117 args.iter().fold(0, |ans, arg| {
118 if let Some(ty) = arg.as_type() {
119 ans.max(ty_complexity(ty))
120 } else {
121 ans
122 }
123 }) + 1
124 }
125
126 _ => 1,
128 }
129}