diff --git a/reid-llvm-lib/src/builder.rs b/reid-llvm-lib/src/builder.rs index 6f015ed..42ab14c 100644 --- a/reid-llvm-lib/src/builder.rs +++ b/reid-llvm-lib/src/builder.rs @@ -14,10 +14,10 @@ use crate::{ util::match_types, }; -#[derive(Clone, Hash, Copy, PartialEq, Eq)] +#[derive(Clone, Hash, Copy, PartialEq, Eq, PartialOrd)] pub struct ModuleValue(pub(crate) usize); -#[derive(Clone, Hash, Copy, PartialEq, Eq)] +#[derive(Clone, Hash, Copy, PartialEq, Eq, PartialOrd)] pub struct TypeValue(pub(crate) ModuleValue, pub(crate) usize); #[derive(Clone, Hash, Copy, PartialEq, Eq)] @@ -517,7 +517,7 @@ impl Builder { } for (a, b) in param_types.iter().zip(params) { if *a != b.get_type(&self)? { - return Err(ErrorKind::Null); // TODO error: params do not match + return Err(ErrorKind::TypesIncompatible(a.clone(), b.get_type(&self)?)); // TODO error: params do not match } } Ok(()) diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index d612fbb..a89b516 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -26,6 +26,8 @@ mod util; pub enum ErrorKind { #[error("NULL error, should never occur!")] Null, + #[error("Types {0:?} and {1:?} incompatible")] + TypesIncompatible(Type, Type), } pub type CompileResult = Result; @@ -498,7 +500,7 @@ pub enum Instr { FunctionCall(FunctionValue, Vec), } -#[derive(Debug, PartialEq, Eq, Clone, Hash)] +#[derive(Debug, PartialEq, Eq, Clone, Hash, PartialOrd)] pub enum Type { I8, I16, diff --git a/reid/src/mir/fmt.rs b/reid/src/mir/fmt.rs index 4cdef21..ec25c10 100644 --- a/reid/src/mir/fmt.rs +++ b/reid/src/mir/fmt.rs @@ -117,7 +117,7 @@ impl Display for TypeDefinition { self.name, self.source_module, if let Some(mod_id) = self.importer { - format!("; imported to {}", mod_id) + format!("; imported by {}", mod_id) } else { String::new() } diff --git a/reid/src/mir/linker.rs b/reid/src/mir/linker.rs index c4ef006..9b688c9 100644 --- a/reid/src/mir/linker.rs +++ b/reid/src/mir/linker.rs @@ -481,18 +481,29 @@ impl<'map> Pass for LinkerPass<'map> { } } + let mut typedef_keys = HashMap::new(); // 4. Import all listed types. for (importer_typekey, imported_module_id) in &imported_types { - let imported_ty_module = modules.get(&imported_module_id).unwrap().module.borrow(); let importee_typekey = CustomTypeKey(importer_typekey.0.clone(), *imported_module_id); + if let Some(module_id) = typedef_keys.get(&importee_typekey) { + if *module_id != importer_module.module_id { + typedef_keys.insert(importee_typekey.clone(), importer_typekey.1); + } + } else { + typedef_keys.insert(importee_typekey.clone(), importer_typekey.1); + } + } + + for (typedef_key, importer_module_id) in &typedef_keys { + let imported_ty_module = modules.get(&typedef_key.1).unwrap().module.borrow(); if let Some(typedef) = imported_ty_module .typedefs .iter() - .find(|ty| CustomTypeKey(ty.name.clone(), ty.source_module) == importee_typekey) + .find(|ty| CustomTypeKey(ty.name.clone(), ty.source_module) == *typedef_key) .cloned() { importer_module.typedefs.push(TypeDefinition { - importer: Some(importer_typekey.1), + importer: Some(*importer_module_id), ..typedef }); }