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 def.variants
36 .iter()
37 .any(|v| v.fields.iter().any(|f| type_needs_drop(*f, type_pool)))
38 }
39 _ => false,
40 }
41}
42
43pub fn drop_fn_name(ty: Type, type_pool: &TypeInternPool) -> Option<String> {
49 match ty.kind() {
50 TypeKind::Struct(id) => {
51 let def = type_pool.struct_def(id);
52 if def.is_builtin && def.destructor.is_some() {
56 return None;
57 }
58 if type_needs_drop(ty, type_pool) {
59 Some(format!("__gruel_drop_{}", def.name))
60 } else {
61 None
62 }
63 }
64 TypeKind::Array(id) => {
65 if type_needs_drop(ty, type_pool) {
66 let (elem, len) = type_pool.array_def(id);
67 Some(format!(
68 "__gruel_drop_array_{}_{}",
69 type_name_component(elem, type_pool),
70 len
71 ))
72 } else {
73 None
74 }
75 }
76 TypeKind::Enum(id) => {
77 if type_needs_drop(ty, type_pool) {
78 let def = type_pool.enum_def(id);
79 Some(format!("__gruel_drop_{}", def.name))
80 } else {
81 None
82 }
83 }
84 _ => None,
85 }
86}
87
88pub fn type_name_component(ty: Type, type_pool: &TypeInternPool) -> String {
91 match ty.kind() {
92 TypeKind::I8 => "i8".to_owned(),
93 TypeKind::I16 => "i16".to_owned(),
94 TypeKind::I32 => "i32".to_owned(),
95 TypeKind::I64 => "i64".to_owned(),
96 TypeKind::U8 => "u8".to_owned(),
97 TypeKind::U16 => "u16".to_owned(),
98 TypeKind::U32 => "u32".to_owned(),
99 TypeKind::U64 => "u64".to_owned(),
100 TypeKind::Isize => "isize".to_owned(),
101 TypeKind::Usize => "usize".to_owned(),
102 TypeKind::F16 => "f16".to_owned(),
103 TypeKind::F32 => "f32".to_owned(),
104 TypeKind::F64 => "f64".to_owned(),
105 TypeKind::Bool => "bool".to_owned(),
106 TypeKind::Unit => "unit".to_owned(),
107 TypeKind::Never => "never".to_owned(),
108 TypeKind::Error => "error".to_owned(),
109 TypeKind::ComptimeType => "comptime_type".to_owned(),
110 TypeKind::ComptimeStr => "comptime_str".to_owned(),
111 TypeKind::ComptimeInt => "comptime_int".to_owned(),
112 TypeKind::Enum(id) => format!("enum{}", id.0),
113 TypeKind::Struct(id) => type_pool.struct_def(id).name.clone(),
114 TypeKind::Array(id) => {
115 let (elem, len) = type_pool.array_def(id);
116 format!("array_{}_{}", type_name_component(elem, type_pool), len)
117 }
118 TypeKind::Module(id) => format!("module{}", id.0),
119 TypeKind::PtrConst(id) => {
120 let pointee = type_pool.ptr_const_def(id);
121 format!("ptr_const_{}", type_name_component(pointee, type_pool))
122 }
123 TypeKind::PtrMut(id) => {
124 let pointee = type_pool.ptr_mut_def(id);
125 format!("ptr_mut_{}", type_name_component(pointee, type_pool))
126 }
127 }
128}