Fix seeing same type multiple times when importing

This commit is contained in:
Sofia 2025-07-23 17:19:27 +03:00
parent 8be6ce1549
commit fe4e41c435
4 changed files with 34 additions and 29 deletions

View File

@ -256,6 +256,7 @@ impl mir::Module {
let mut typedefs = self.typedefs.clone(); let mut typedefs = self.typedefs.clone();
typedefs.sort_by(|a, b| b.source_module.cmp(&a.source_module)); typedefs.sort_by(|a, b| b.source_module.cmp(&a.source_module));
dbg!(&self.module_id, &typedefs);
for typedef in typedefs { for typedef in typedefs {
let type_key = CustomTypeKey(typedef.name.clone(), typedef.source_module); let type_key = CustomTypeKey(typedef.name.clone(), typedef.source_module);
let type_value = match &typedef.kind { let type_value = match &typedef.kind {
@ -835,7 +836,6 @@ impl mir::Expression {
.expect("index returned none!") .expect("index returned none!")
.instr(); .instr();
dbg!(&ty);
let TypeKind::CodegenPtr(inner) = ty else { let TypeKind::CodegenPtr(inner) = ty else {
panic!(); panic!();
}; };

View File

@ -103,6 +103,8 @@ impl<'map> Pass for LinkerPass<'map> {
let mut modules_to_process: Vec<Rc<RefCell<_>>> = modules.values().cloned().collect(); let mut modules_to_process: Vec<Rc<RefCell<_>>> = modules.values().cloned().collect();
let mut already_imported_types = HashSet::<CustomTypeKey>::new();
while let Some(module) = modules_to_process.pop() { while let Some(module) = modules_to_process.pop() {
let mut importer_module = module.borrow_mut(); let mut importer_module = module.borrow_mut();
@ -232,28 +234,30 @@ impl<'map> Pass for LinkerPass<'map> {
} }
} }
fn import_type(_: &String, ty: &TypeKind) -> (TypeKind, Vec<CustomTypeKey>) { fn import_type(ty: &TypeKind) -> Vec<CustomTypeKey> {
let mut imported_types = Vec::new(); let mut imported_types = Vec::new();
let ty = match &ty { match &ty {
TypeKind::CustomType(key) => { TypeKind::CustomType(key) => imported_types.push(key.clone()),
imported_types.push(key.clone()); TypeKind::Borrow(ty, _) => imported_types.extend(import_type(ty)),
TypeKind::CustomType(key.clone()) TypeKind::Array(ty, _) => imported_types.extend(import_type(ty)),
} TypeKind::UserPtr(ty) => imported_types.extend(import_type(ty)),
_ => ty.clone(), TypeKind::CodegenPtr(ty) => imported_types.extend(import_type(ty)),
_ => {}
}; };
(ty, imported_types) imported_types
} }
let mut imported_types = Vec::new(); let mut imported_types = Vec::new();
let (return_type, types) = import_type(&imported_mod_name, &func.return_type); let types = import_type(&func.return_type);
let return_type = func.return_type.clone();
imported_types.extend(types); imported_types.extend(types);
let mut param_tys = Vec::new(); let mut param_tys = Vec::new();
for (param_name, param_ty) in &func.parameters { for (param_name, param_ty) in &func.parameters {
let (param_type, types) = import_type(&imported_mod_name, &param_ty); let types = import_type(&param_ty);
imported_types.extend(types); imported_types.extend(types);
param_tys.push((param_name.clone(), param_type)); param_tys.push((param_name.clone(), param_ty.clone()));
} }
fn find_inner_types( fn find_inner_types(
@ -303,6 +307,14 @@ impl<'map> Pass for LinkerPass<'map> {
seen.extend(inner); seen.extend(inner);
} }
// TODO: Unable to import same-named type from multiple places..
let seen = seen
.difference(&already_imported_types)
.cloned()
.collect::<HashSet<_>>();
already_imported_types.extend(seen.clone());
for typekey in seen.into_iter() { for typekey in seen.into_iter() {
let typedef = imported_mod_typedefs let typedef = imported_mod_typedefs
.iter() .iter()
@ -317,7 +329,7 @@ impl<'map> Pass for LinkerPass<'map> {
name: func_name, name: func_name,
is_pub: false, is_pub: false,
is_imported: false, is_imported: false,
return_type: return_type, return_type,
parameters: param_tys, parameters: param_tys,
kind: super::FunctionDefinitionKind::Extern(true), kind: super::FunctionDefinitionKind::Extern(true),
source: imported_mod_id, source: imported_mod_id,

View File

@ -774,21 +774,15 @@ impl TypeKind {
fn is_known(&self, refs: &TypeRefs, state: &TypecheckPassState) -> Result<(), ErrorKind> { fn is_known(&self, refs: &TypeRefs, state: &TypecheckPassState) -> Result<(), ErrorKind> {
match &self { match &self {
TypeKind::Array(type_kind, _) => type_kind.as_ref().is_known(refs, state), TypeKind::Array(type_kind, _) => type_kind.as_ref().is_known(refs, state),
TypeKind::CustomType(custom_type_key) => { TypeKind::CustomType(custom_type_key) => state
if custom_type_key.1 == state.module_id.unwrap() { .scope
state .types
.scope .get(custom_type_key)
.types .map(|_| ())
.get(custom_type_key) .ok_or(ErrorKind::NoSuchType(
.map(|_| ()) custom_type_key.0.clone(),
.ok_or(ErrorKind::NoSuchType( state.module_id.unwrap(),
custom_type_key.0.clone(), )),
state.module_id.unwrap(),
))
} else {
Ok(())
}
}
TypeKind::Borrow(type_kind, _) => type_kind.is_known(refs, state), TypeKind::Borrow(type_kind, _) => type_kind.is_known(refs, state),
TypeKind::UserPtr(type_kind) => type_kind.is_known(refs, state), TypeKind::UserPtr(type_kind) => type_kind.is_known(refs, state),
TypeKind::CodegenPtr(type_kind) => type_kind.is_known(refs, state), TypeKind::CodegenPtr(type_kind) => type_kind.is_known(refs, state),

View File

@ -322,7 +322,6 @@ impl Expression {
// Check that the resolved type is at least a struct, no // Check that the resolved type is at least a struct, no
// need for further resolution. // need for further resolution.
let kind = expr_ty.resolve_weak().unwrap(); let kind = expr_ty.resolve_weak().unwrap();
dbg!(&state.scope);
match kind { match kind {
CustomType(key) => { CustomType(key) => {
let struct_ty = state let struct_ty = state