use crate::ir::{NamedType, TypeDef, TypeRef, UnionType, NULL_ID};
pub fn is_null_typeref(types: &[NamedType], r: &TypeRef) -> bool {
types
.iter()
.any(|nt| nt.id == *r && matches!(nt.definition, TypeDef::Null))
}
pub fn peel_nullable<'a>(types: &'a [NamedType], r: &TypeRef) -> Option<&'a TypeRef> {
let nt = types.iter().find(|nt| &nt.id == r)?;
let TypeDef::Union(u) = &nt.definition else {
return None;
};
if u.variants.len() != 2 {
return None;
}
let null_idx = u
.variants
.iter()
.position(|v| is_null_typeref(types, &v.r#type))?;
let other_idx = if null_idx == 0 { 1 } else { 0 };
Some(&u.variants[other_idx].r#type)
}
pub fn union_has_null(types: &[NamedType], u: &UnionType) -> bool {
u.variants.iter().any(|v| is_null_typeref(types, &v.r#type))
}
pub fn is_canonical_null_id(r: &TypeRef) -> bool {
r == NULL_ID
}