Fix typedef ordering in codegen

This commit is contained in:
Sofia 2025-08-06 22:01:28 +03:00
parent a5c7823a29
commit 82b67dfaaa
2 changed files with 34 additions and 19 deletions

View File

@ -125,6 +125,17 @@ impl mir::GlobalKind {
} }
} }
fn get_typekey(ty: &TypeKind) -> Option<CustomTypeKey> {
match ty {
TypeKind::Array(type_kind, _) => get_typekey(type_kind.as_ref()),
TypeKind::CustomType(custom_type_key) => Some(custom_type_key.clone()),
TypeKind::Borrow(type_kind, _) => get_typekey(type_kind.as_ref()),
TypeKind::UserPtr(type_kind) => get_typekey(type_kind.as_ref()),
TypeKind::CodegenPtr(type_kind) => get_typekey(type_kind.as_ref()),
_ => None,
}
}
impl mir::Module { impl mir::Module {
fn codegen<'ctx>( fn codegen<'ctx>(
&'ctx self, &'ctx self,
@ -186,33 +197,35 @@ impl mir::Module {
// somewhat easily sort the type-definitions such that we can process // somewhat easily sort the type-definitions such that we can process
// the ones with no depencencies first, and later the ones that depend // the ones with no depencencies first, and later the ones that depend
// on the earlier ones. // on the earlier ones.
let mut typekeys_seen = HashSet::new(); let mut typekeys_seen: HashSet<CustomTypeKey> = HashSet::new();
let mut typedefs_sorted = Vec::new(); let mut typedefs_sorted: Vec<TypeDefinition> = Vec::new();
let mut typedefs_left = self.typedefs.clone(); let mut typedefs_left = self.typedefs.clone();
typedefs_left.reverse();
while let Some(typedef) = typedefs_left.pop() { while let Some(typedef) = typedefs_left.pop() {
match &typedef.kind { let is_ok = match &typedef.kind {
TypeDefinitionKind::Struct(StructType(fields)) => { TypeDefinitionKind::Struct(StructType(fields)) => {
let mut is_ok = true; let mut field_iter = fields.iter();
for field in fields { loop {
match &field.1 { if let Some(field) = field_iter.next() {
TypeKind::CustomType(type_key) => { if let Some(key) = get_typekey(&field.1) {
if !typekeys_seen.contains(type_key) { if typekeys_seen.contains(&key) {
is_ok = false; break true;
break; } else {
break false;
} }
} }
_ => {} } else {
break true;
} }
} }
if is_ok {
typekeys_seen.insert(CustomTypeKey(typedef.name.clone(), typedef.source_module));
typedefs_sorted.push(typedef);
} else {
typedefs_left.insert(0, typedef.clone());
}
} }
}; };
if is_ok {
typekeys_seen.insert(CustomTypeKey(typedef.name.clone(), typedef.source_module));
typedefs_sorted.push(typedef);
} else {
typedefs_left.insert(0, typedef.clone());
}
} }
for typedef in typedefs_sorted { for typedef in typedefs_sorted {

View File

@ -686,7 +686,9 @@ fn resolve_types_recursively(
return Err(ErrorKind::CyclicalType(type_key.0.clone())); return Err(ErrorKind::CyclicalType(type_key.0.clone()));
} }
types.insert(type_key.clone(), resolved_ty.1); if type_key.1 != resolved_ty.1 {
types.insert(type_key.clone(), resolved_ty.1);
}
seen.insert(resolved_ty.clone()); seen.insert(resolved_ty.clone());
let resolved = modules let resolved = modules