rapx/analysis/core/ownedheap_analysis/
mod.rs1pub mod default;
2
3use rustc_middle::ty::{Ty, TyKind};
4use rustc_span::def_id::DefId;
5
6use std::{
7 collections::{HashMap, HashSet},
8 env,
9 fmt::{self, Display},
10};
11
12use crate::{rap_info, utils::source::get_fn_name_byid, Analysis};
13
14#[repr(u8)]
15#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
16pub enum OwnedHeap {
17 False = 0,
18 True = 1,
19 Unknown = 2,
20}
21
22impl Default for OwnedHeap {
23 fn default() -> Self {
24 Self::Unknown
25 }
26}
27
28impl OwnedHeap {
29 pub fn is_onheap(&self) -> bool {
30 match self {
31 OwnedHeap::True => true,
32 _ => false,
33 }
34 }
35}
36
37impl Display for OwnedHeap {
38 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
39 let name = match self {
40 OwnedHeap::False => "0",
41 OwnedHeap::True => "1",
42 OwnedHeap::Unknown => "2",
43 };
44 write!(f, "{}", name)
45 }
46}
47
48pub type OHAResultMap = HashMap<DefId, Vec<(OwnedHeap, Vec<bool>)>>;
56pub struct OHAResultMapWrapper(pub HashMap<DefId, Vec<(OwnedHeap, Vec<bool>)>>);
57
58impl Display for OHAResultMapWrapper {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 writeln!(f, "=== Print owned heap analysis resuts ===")?;
61 for (def_id, units) in &self.0 {
62 let fn_name = get_fn_name_byid(def_id);
63 let owning = units
64 .iter()
65 .map(Self::format_heap_unit)
66 .collect::<Vec<_>>()
67 .join(", ");
68 writeln!(f, "Type: {:?}: {}", fn_name, owning)?;
69 }
70 Ok(())
71 }
72}
73
74impl OHAResultMapWrapper {
75 fn format_heap_unit((heap, bits): &(OwnedHeap, Vec<bool>)) -> String {
76 let bit_str = bits
77 .iter()
78 .map(|b| if *b { "1" } else { "0" })
79 .collect::<Vec<_>>()
80 .join(",");
81 format!("{:?}, <{}>", heap, bit_str)
82 }
83}
84pub trait OwnedHeapAnalysis: Analysis {
87 fn get_all_items(&self) -> OHAResultMap;
89
90 fn is_heapowner<'tcx>(hares: OHAResultMap, ty: Ty<'tcx>) -> Result<bool, &'static str> {
93 match ty.kind() {
94 TyKind::Adt(adtdef, ..) => {
95 let heapinfo = hares.get(&adtdef.0 .0.did).unwrap();
96 for item in heapinfo {
97 if item.0 == OwnedHeap::True {
98 return Ok(true);
99 }
100 }
101 Ok(false)
102 }
103 _ => Err("The input is not an ADT"),
104 }
105 }
106
107 fn maybe_heapowner<'tcx>(hares: OHAResultMap, ty: Ty<'tcx>) -> Result<bool, &'static str> {
110 match ty.kind() {
111 TyKind::Adt(adtdef, ..) => {
112 let heapinfo = hares.get(&adtdef.0 .0.did).unwrap();
113 for item in heapinfo {
114 if item.0 == OwnedHeap::False && item.1.contains(&true) {
115 return Ok(true);
116 }
117 }
118 Ok(false)
119 }
120 _ => Err("The input is not an ADT"),
121 }
122 }
123}