1use gruel_air::{Type, TypeInternPool, TypeKind};
13
14pub fn type_needs_drop(ty: Type, type_pool: &TypeInternPool) -> bool {
21 match ty.kind() {
22 TypeKind::Struct(id) => {
23 let def = type_pool.struct_def(id);
24 if def.destructor.is_some() {
25 return true;
26 }
27 def.fields.iter().any(|f| type_needs_drop(f.ty, type_pool))
28 }
29 TypeKind::Array(id) => {
30 let (elem, _) = type_pool.array_def(id);
31 type_needs_drop(elem, type_pool)
32 }
33 TypeKind::Enum(id) => {
34 let def = type_pool.enum_def(id);
35 if def.destructor.is_some() {
36 return true;
37 }
38 def.variants
39 .iter()
40 .any(|v| v.fields.iter().any(|f| type_needs_drop(*f, type_pool)))
41 }
42 TypeKind::Vec(_) => true,
44 _ => false,
45 }
46}
47
48pub fn drop_fn_name(ty: Type, type_pool: &TypeInternPool) -> Option<String> {
58 match ty.kind() {
59 TypeKind::Struct(id) => {
60 let def = type_pool.struct_def(id);
61 if type_needs_drop(ty, type_pool) {
62 Some(format!("__gruel_drop_{}", def.name))
63 } else {
64 None
65 }
66 }
67 TypeKind::Array(id) => {
68 if type_needs_drop(ty, type_pool) {
69 let (elem, len) = type_pool.array_def(id);
70 Some(format!(
71 "__gruel_drop_array_{}_{}",
72 type_name_component(elem, type_pool),
73 len
74 ))
75 } else {
76 None
77 }
78 }
79 TypeKind::Enum(id) => {
80 if type_needs_drop(ty, type_pool) {
81 let def = type_pool.enum_def(id);
82 Some(format!("__gruel_drop_{}", def.name))
83 } else {
84 None
85 }
86 }
87 _ => None,
88 }
89}
90
91pub fn type_name_component(ty: Type, type_pool: &TypeInternPool) -> String {
94 match ty.kind() {
95 TypeKind::I8 => "i8".to_owned(),
96 TypeKind::I16 => "i16".to_owned(),
97 TypeKind::I32 => "i32".to_owned(),
98 TypeKind::I64 => "i64".to_owned(),
99 TypeKind::U8 => "u8".to_owned(),
100 TypeKind::U16 => "u16".to_owned(),
101 TypeKind::U32 => "u32".to_owned(),
102 TypeKind::U64 => "u64".to_owned(),
103 TypeKind::Isize => "isize".to_owned(),
104 TypeKind::Usize => "usize".to_owned(),
105 TypeKind::F16 => "f16".to_owned(),
106 TypeKind::F32 => "f32".to_owned(),
107 TypeKind::F64 => "f64".to_owned(),
108 TypeKind::Bool => "bool".to_owned(),
109 TypeKind::Char => "char".to_owned(),
110 TypeKind::Unit => "unit".to_owned(),
111 TypeKind::Never => "never".to_owned(),
112 TypeKind::Error => "error".to_owned(),
113 TypeKind::ComptimeType => "comptime_type".to_owned(),
114 TypeKind::ComptimeStr => "comptime_str".to_owned(),
115 TypeKind::ComptimeInt => "comptime_int".to_owned(),
116 TypeKind::CSchar => "c_schar".to_owned(),
118 TypeKind::CShort => "c_short".to_owned(),
119 TypeKind::CInt => "c_int".to_owned(),
120 TypeKind::CLong => "c_long".to_owned(),
121 TypeKind::CLonglong => "c_longlong".to_owned(),
122 TypeKind::CUchar => "c_uchar".to_owned(),
123 TypeKind::CUshort => "c_ushort".to_owned(),
124 TypeKind::CUint => "c_uint".to_owned(),
125 TypeKind::CUlong => "c_ulong".to_owned(),
126 TypeKind::CUlonglong => "c_ulonglong".to_owned(),
127 TypeKind::CFloat => "c_float".to_owned(),
128 TypeKind::CDouble => "c_double".to_owned(),
129 TypeKind::CVoid => "c_void".to_owned(),
130 TypeKind::Enum(id) => format!("enum{}", id.0),
131 TypeKind::Struct(id) => type_pool.struct_def(id).name.clone(),
132 TypeKind::Array(id) => {
133 let (elem, len) = type_pool.array_def(id);
134 format!("array_{}_{}", type_name_component(elem, type_pool), len)
135 }
136 TypeKind::Module(id) => format!("module{}", id.0),
137 TypeKind::PtrConst(id) => {
138 let pointee = type_pool.ptr_const_def(id);
139 format!("ptr_const_{}", type_name_component(pointee, type_pool))
140 }
141 TypeKind::PtrMut(id) => {
142 let pointee = type_pool.ptr_mut_def(id);
143 format!("ptr_mut_{}", type_name_component(pointee, type_pool))
144 }
145 TypeKind::Ref(id) => {
146 let referent = type_pool.ref_def(id);
147 format!("ref_{}", type_name_component(referent, type_pool))
148 }
149 TypeKind::MutRef(id) => {
150 let referent = type_pool.mut_ref_def(id);
151 format!("mut_ref_{}", type_name_component(referent, type_pool))
152 }
153 TypeKind::Slice(id) => {
154 let elem = type_pool.slice_def(id);
155 format!("slice_{}", type_name_component(elem, type_pool))
156 }
157 TypeKind::MutSlice(id) => {
158 let elem = type_pool.mut_slice_def(id);
159 format!("mut_slice_{}", type_name_component(elem, type_pool))
160 }
161 TypeKind::Vec(id) => {
162 let elem = type_pool.vec_def(id);
163 format!("vec_{}", type_name_component(elem, type_pool))
164 }
165 TypeKind::Interface(id) => format!("interface{}", id.0),
166 }
167}