diff --git a/reid-llvm-lib/src/builder.rs b/reid-llvm-lib/src/builder.rs index eaf875e..67de72b 100644 --- a/reid-llvm-lib/src/builder.rs +++ b/reid-llvm-lib/src/builder.rs @@ -4,8 +4,8 @@ use std::{cell::RefCell, rc::Rc}; use crate::{ - Block, BlockData, CustomTypeKind, FunctionData, Instr, InstructionData, ModuleData, - NamedStruct, TerminatorKind, Type, TypeCategory, TypeData, + Block, BlockData, CompileResult, CustomTypeKind, ErrorKind, FunctionData, Instr, + InstructionData, ModuleData, NamedStruct, TerminatorKind, Type, TypeCategory, TypeData, debug_information::{ DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue, InstructionDebugRecordData, @@ -151,7 +151,7 @@ impl Builder { block_val: &BlockValue, data: InstructionData, name: String, - ) -> Result { + ) -> CompileResult { unsafe { let mut modules = self.modules.borrow_mut(); let module = modules.get_unchecked_mut(block_val.0.0.0); @@ -236,14 +236,14 @@ impl Builder { &self, block: &BlockValue, value: TerminatorKind, - ) -> Result<(), ()> { + ) -> CompileResult<()> { unsafe { let mut modules = self.modules.borrow_mut(); let module = modules.get_unchecked_mut(block.0.0.0); let function = module.functions.get_unchecked_mut(block.0.1); let block = function.blocks.get_unchecked_mut(block.1); if let Some(_) = &block.data.terminator { - Err(()) + Err(ErrorKind::Null) } else { block.data.terminator = Some(value); Ok(()) @@ -255,14 +255,14 @@ impl Builder { &self, block: &BlockValue, location: DebugLocationValue, - ) -> Result<(), ()> { + ) -> CompileResult<()> { unsafe { let mut modules = self.modules.borrow_mut(); let module = modules.get_unchecked_mut(block.0.0.0); let function = module.functions.get_unchecked_mut(block.0.1); let block = function.blocks.get_unchecked_mut(block.1); if let Some(_) = &block.data.terminator_location { - Err(()) + Err(ErrorKind::Null) } else { block.data.terminator_location = Some(location); Ok(()) @@ -270,7 +270,7 @@ impl Builder { } } - pub(crate) unsafe fn delete_block(&self, block: &BlockValue) -> Result<(), ()> { + pub(crate) unsafe fn delete_block(&self, block: &BlockValue) -> CompileResult<()> { unsafe { let mut modules = self.modules.borrow_mut(); let module = modules.get_unchecked_mut(block.0.0.0); @@ -349,7 +349,7 @@ impl Builder { self.modules.clone() } - pub fn check_instruction(&self, instruction: &InstructionValue) -> Result<(), ()> { + pub fn check_instruction(&self, instruction: &InstructionValue) -> CompileResult<()> { unsafe { match self.instr_data(&instruction).kind { Instr::Param(_) => Ok(()), @@ -372,7 +372,7 @@ impl Builder { if t.comparable() || t.category() != TypeCategory::Integer { Ok(()) } else { - Err(()) // TODO error: Types not comparable + Err(ErrorKind::Null) // TODO error: Types not comparable } } Instr::FCmp(_, lhs, rhs) => { @@ -380,17 +380,17 @@ impl Builder { if t.comparable() || t.category() != TypeCategory::Real { Ok(()) } else { - Err(()) // TODO error: Types not comparable + Err(ErrorKind::Null) // TODO error: Types not comparable } } Instr::FunctionCall(fun, params) => { let param_types = self.function_data(&fun).params; if param_types.len() != params.len() { - return Err(()); // TODO error: invalid amount of params + return Err(ErrorKind::Null); // TODO error: invalid amount of params } for (a, b) in param_types.iter().zip(params) { if *a != b.get_type(&self)? { - return Err(()); // TODO error: params do not match + return Err(ErrorKind::Null); // TODO error: params do not match } } Ok(()) @@ -403,7 +403,7 @@ impl Builder { // incoming values come from blocks that are added later // than the one where this one exists. - let first = iter.next().ok_or(())?; + let first = iter.next().ok_or(ErrorKind::Null)?; for item in iter { match_types(first, item, &self)?; } @@ -416,10 +416,10 @@ impl Builder { if *ptr_ty_inner == load_ty { Ok(()) } else { - Err(()) // TODO error: inner type mismatch + Err(ErrorKind::Null) // TODO error: inner type mismatch } } else { - Err(()) // TODO error: not a pointer + Err(ErrorKind::Null) // TODO error: not a pointer } } Instr::Store(ptr, _) => { @@ -427,7 +427,7 @@ impl Builder { if let Type::Ptr(_) = ty { Ok(()) } else { - Err(()) // TODO error: not a pointer + Err(ErrorKind::Null) // TODO error: not a pointer } } Instr::ArrayAlloca(_, _) => Ok(()), @@ -435,7 +435,7 @@ impl Builder { let ptr_ty = ptr_val.get_type(&self)?; match ptr_ty { Type::Ptr(_) => Ok(()), - _ => Err(()), + _ => Err(ErrorKind::Null), } } Instr::GetStructElemPtr(ptr_val, idx) => { @@ -445,16 +445,16 @@ impl Builder { match self.type_data(&val).kind { CustomTypeKind::NamedStruct(NamedStruct(_, fields)) => { if fields.len() <= idx as usize { - return Err(()); // TODO error: no such field + return Err(ErrorKind::Null); // TODO error: no such field } } } Ok(()) } else { - Err(()) // TODO error: not a struct + Err(ErrorKind::Null) // TODO error: not a struct } } else { - Err(()) // TODO error: not a pointer + Err(ErrorKind::Null) // TODO error: not a pointer } } Instr::ExtractValue(val, _) => { @@ -464,7 +464,7 @@ impl Builder { CustomTypeKind::NamedStruct(_) => Ok(()), }, Type::Array(_, _) => Ok(()), - _ => Err(()), + _ => Err(ErrorKind::Null), } } Instr::Trunc(instr, ty) => instr.cast_to(self, &ty).map(|_| ()), @@ -545,7 +545,7 @@ impl InstructionValue { } } - pub(crate) fn get_type(&self, builder: &Builder) -> Result { + pub(crate) fn get_type(&self, builder: &Builder) -> CompileResult { use Instr::*; unsafe { match &builder.instr_data(self).kind { @@ -554,7 +554,7 @@ impl InstructionValue { .params .get(*nth) .cloned() - .ok_or(()), + .ok_or(ErrorKind::Null), Constant(c) => Ok(c.get_type()), Add(lhs, rhs) => match_types(lhs, rhs, &builder), FAdd(lhs, rhs) => match_types(lhs, rhs, &builder), @@ -572,7 +572,10 @@ impl InstructionValue { ICmp(_, _, _) => Ok(Type::Bool), FCmp(_, _, _) => Ok(Type::Bool), FunctionCall(function_value, _) => Ok(builder.function_data(function_value).ret), - Phi(values) => values.first().ok_or(()).and_then(|v| v.get_type(&builder)), + Phi(values) => values + .first() + .ok_or(ErrorKind::Null) + .and_then(|v| v.get_type(&builder)), Alloca(ty) => Ok(Type::Ptr(Box::new(ty.clone()))), Load(_, ty) => Ok(ty.clone()), Store(_, value) => value.get_type(builder), @@ -614,7 +617,7 @@ impl InstructionValue { } } Type::Array(elem_ty, _) => *elem_ty.clone(), - _ => return Err(()), + _ => return Err(ErrorKind::Null), }) } Trunc(instr, ty) => instr.cast_to(builder, ty).map(|_| ty.clone()), @@ -633,9 +636,9 @@ impl InstructionValue { } } - fn cast_to(&self, builder: &Builder, ty: &Type) -> Result { + fn cast_to(&self, builder: &Builder, ty: &Type) -> CompileResult { self.get_type(builder)? .cast_instruction(*self, &ty) - .ok_or(()) + .ok_or(ErrorKind::Null) } } diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index 80e9ac5..a916c1f 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -17,6 +17,14 @@ mod fmt; mod pad_adapter; mod util; +#[derive(thiserror::Error, Debug, Clone, PartialEq, PartialOrd)] +pub enum ErrorKind { + #[error("NULL error, should never occur!")] + Null, +} + +pub type CompileResult = Result; + #[derive(Debug)] pub struct Context { builder: Builder, @@ -254,7 +262,7 @@ impl<'builder> Block<'builder> { &mut self, name: T, instruction: Instr, - ) -> Result { + ) -> CompileResult { unsafe { self.builder.add_instruction( &self.value, @@ -268,7 +276,7 @@ impl<'builder> Block<'builder> { } } - pub fn build(&mut self, instruction: Instr) -> Result { + pub fn build(&mut self, instruction: Instr) -> CompileResult { unsafe { let name = instruction.default_name().to_owned(); self.builder.add_instruction( @@ -297,16 +305,16 @@ impl<'builder> Block<'builder> { } } - pub fn terminate(&mut self, instruction: TerminatorKind) -> Result<(), ()> { + pub fn terminate(&mut self, instruction: TerminatorKind) -> CompileResult<()> { unsafe { self.builder.terminate(&self.value, instruction) } } - pub fn set_terminator_location(&mut self, location: DebugLocationValue) -> Result<(), ()> { + pub fn set_terminator_location(&mut self, location: DebugLocationValue) -> CompileResult<()> { unsafe { self.builder.set_terminator_location(&self.value, location) } } /// Delete block if it is unused. Return true if deleted, false if not. - pub fn delete_if_unused(&mut self) -> Result { + pub fn delete_if_unused(&mut self) -> CompileResult { unsafe { if !self.builder.is_block_used(self.value()) { self.builder.delete_block(&self.value)?; @@ -682,7 +690,7 @@ pub enum TypeCategory { } impl TerminatorKind { - pub(crate) fn get_type(&self, builder: &Builder) -> Result { + pub(crate) fn get_type(&self, builder: &Builder) -> CompileResult { use TerminatorKind::*; match self { Ret(instr_val) => instr_val.get_type(builder), diff --git a/reid-llvm-lib/src/util.rs b/reid-llvm-lib/src/util.rs index bb405b8..be7735a 100644 --- a/reid-llvm-lib/src/util.rs +++ b/reid-llvm-lib/src/util.rs @@ -14,7 +14,7 @@ use llvm_sys::{ }; use crate::{ - Type, + CompileResult, ErrorKind, Type, builder::{Builder, InstructionValue}, }; @@ -117,12 +117,16 @@ pub fn match_types( lhs: &InstructionValue, rhs: &InstructionValue, builder: &Builder, -) -> Result { +) -> CompileResult { let lhs_type = lhs.get_type(&builder); let rhs_type = rhs.get_type(&builder); if let (Ok(lhs_t), Ok(rhs_t)) = (lhs_type, rhs_type) { - if lhs_t == rhs_t { Ok(lhs_t) } else { Err(()) } + if lhs_t == rhs_t { + Ok(lhs_t) + } else { + Err(ErrorKind::Null) + } } else { - Err(()) + Err(ErrorKind::Null) } } diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index dce8b5d..a8145d8 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -20,8 +20,15 @@ use crate::{ self, implement::TypeCategory, CustomTypeKey, Metadata, NamedVariableRef, SourceModuleId, StructField, StructType, TypeDefinition, TypeDefinitionKind, TypeKind, VagueLiteral, }, + util::try_all, }; +#[derive(thiserror::Error, Debug, Clone, PartialEq, PartialOrd)] +pub enum ErrorKind { + #[error("NULL error, should never occur!")] + Null, +} + /// Context that contains all of the given modules as complete codegenerated /// LLIR that can then be finally compiled into LLVM IR. #[derive(Debug)] @@ -39,16 +46,16 @@ impl<'ctx> CodegenContext<'ctx> { impl mir::Context { /// Compile MIR [`Context`] into [`CodegenContext`] containing LLIR. - pub fn codegen<'ctx>(&self, context: &'ctx Context) -> CodegenContext<'ctx> { + pub fn codegen<'ctx>(&self, context: &'ctx Context) -> Result, ErrorKind> { let mut modules = HashMap::new(); let mut modules_sorted = self.modules.iter().map(|(_, m)| m).collect::>(); modules_sorted.sort_by(|m1, m2| m2.module_id.cmp(&m1.module_id)); for module in &modules_sorted { - let codegen = module.codegen(context, modules.clone()); + let codegen = module.codegen(context, modules.clone())?; modules.insert(module.module_id, codegen); } - CodegenContext { context } + Ok(CodegenContext { context }) } } @@ -194,7 +201,7 @@ impl mir::Module { &'ctx self, context: &'ctx Context, modules: HashMap>, - ) -> ModuleCodegen<'ctx> { + ) -> Result, ErrorKind> { let mut module = context.module(&self.name, self.is_main); let tokens = &self.tokens; @@ -430,7 +437,7 @@ impl mir::Module { }; let state = State::default(); - if let Some(ret) = block.codegen(&mut scope, &state) { + if let Some(ret) = block.codegen(&mut scope, &state)? { scope.block.terminate(Term::Ret(ret.instr())).unwrap(); } else { if !scope.block.delete_if_unused().unwrap() { @@ -451,7 +458,7 @@ impl mir::Module { } } - ModuleCodegen { module } + Ok(ModuleCodegen { module }) } } @@ -460,9 +467,9 @@ impl mir::Block { &self, mut scope: &mut Scope<'ctx, 'a>, state: &State, - ) -> Option { + ) -> Result, ErrorKind> { for stmt in &self.statements { - stmt.codegen(&mut scope, state).map(|s| { + stmt.codegen(&mut scope, state)?.map(|s| { if let Some(debug) = &scope.debug { let location = stmt.1.into_debug(scope.tokens, debug.scope).unwrap(); let loc_val = debug.info.location(&debug.scope, location); @@ -472,22 +479,30 @@ impl mir::Block { } if let Some((kind, expr)) = &self.return_expression { - let ret = expr.codegen(&mut scope, &mut state.load(true)); + let ret = expr.codegen(&mut scope, &mut state.load(true))?; match kind { mir::ReturnKind::Hard => { - scope.block.terminate(Term::Ret(ret?.instr())).unwrap(); - None + if let Some(ret) = ret { + scope.block.terminate(Term::Ret(ret.instr())).unwrap(); + } else { + scope.block.terminate(Term::RetVoid).unwrap(); + } + Ok(None) } - mir::ReturnKind::Soft => ret, + mir::ReturnKind::Soft => Ok(ret), } } else { - None + Ok(None) } } } impl mir::Statement { - fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, state: &State) -> Option { + fn codegen<'ctx, 'a>( + &self, + scope: &mut Scope<'ctx, 'a>, + state: &State, + ) -> Result, ErrorKind> { let location = scope.debug.clone().map(|d| { let location = self.1.into_debug(scope.tokens, d.scope).unwrap(); d.info.location(&d.scope, location) @@ -495,7 +510,7 @@ impl mir::Statement { match &self.0 { mir::StmtKind::Let(NamedVariableRef(ty, name, _), mutable, expression) => { - let value = expression.codegen(scope, &state).unwrap(); + let value = expression.codegen(scope, &state)?.unwrap(); let alloca = scope .block @@ -545,14 +560,17 @@ impl mir::Statement { }, ); } - None + Ok(None) } mir::StmtKind::Set(lhs, rhs) => { let lhs_value = lhs - .codegen(scope, &state.load(false)) + .codegen(scope, &state.load(false))? .expect("non-returning LHS snuck into codegen!"); let rhs_value = rhs.codegen(scope, state)?; + let Some(rhs_value) = rhs_value else { + return Ok(None); + }; let backing_var = if let Some(var) = lhs.backing_var() { &format!("store.{}", var.1) @@ -576,7 +594,7 @@ impl mir::Statement { } }; - None + Ok(None) } mir::StmtKind::Import(_) => todo!(), mir::StmtKind::Expression(expression) => expression.codegen(scope, state), @@ -585,7 +603,11 @@ impl mir::Statement { } impl mir::Expression { - fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, state: &State) -> Option { + fn codegen<'ctx, 'a>( + &self, + scope: &mut Scope<'ctx, 'a>, + state: &State, + ) -> Result, ErrorKind> { let location = if let Some(debug) = &scope.debug { Some(debug.info.location( &debug.scope, @@ -634,11 +656,11 @@ impl mir::Expression { )), mir::ExprKind::BinOp(binop, lhs_exp, rhs_exp) => { let lhs = lhs_exp - .codegen(scope, state) + .codegen(scope, state)? .expect("lhs has no return value") .instr(); let rhs = rhs_exp - .codegen(scope, state) + .codegen(scope, state)? .expect("rhs has no return value") .instr(); let lhs_type = lhs_exp @@ -721,11 +743,17 @@ impl mir::Expression { let ret_type = ret_type_kind.get_type(scope.type_values, scope.types); - let params = call - .parameters - .iter() - .map(|e| e.codegen(scope, state).unwrap()) - .collect::>(); + let params = try_all( + call.parameters + .iter() + .map(|e| e.codegen(scope, state)) + .collect::>(), + ) + .map_err(|e| e.first().cloned().unwrap())? + .into_iter() + .map(|v| v.unwrap()) + .collect::>(); + let param_instrs = params.iter().map(|e| e.instr()).collect(); let callee = scope .functions @@ -782,13 +810,13 @@ impl mir::Expression { None } } - mir::ExprKind::If(if_expression) => if_expression.codegen(scope, state), + mir::ExprKind::If(if_expression) => if_expression.codegen(scope, state)?, mir::ExprKind::Block(block) => { let inner = scope.function.ir.block("inner"); scope.block.terminate(Term::Br(inner.value())).unwrap(); let mut inner_scope = scope.with_block(inner); - let ret = if let Some(ret) = block.codegen(&mut inner_scope, state) { + let ret = if let Some(ret) = block.codegen(&mut inner_scope, state)? { Some(ret) } else { None @@ -800,10 +828,10 @@ impl mir::Expression { } mir::ExprKind::Indexed(expression, val_t, idx_expr) => { let StackValue(kind, ty) = expression - .codegen(scope, &state.load(false)) + .codegen(scope, &state.load(false))? .expect("array returned none!"); let idx = idx_expr - .codegen(scope, &state.load(true)) + .codegen(scope, &state.load(true))? .expect("index returned none!") .instr(); @@ -877,10 +905,17 @@ impl mir::Expression { } } mir::ExprKind::Array(expressions) => { - let stack_value_list = expressions - .iter() - .map(|e| e.codegen(scope, state).unwrap()) - .collect::>(); + let stack_value_list: Vec<_> = try_all( + expressions + .iter() + .map(|e| e.codegen(scope, state)) + .collect::>(), + ) + .map_err(|e| e.first().cloned().unwrap())? + .into_iter() + .map(|v| v.unwrap()) + .collect(); + let instr_list = stack_value_list .iter() .map(|s| s.instr()) @@ -944,7 +979,7 @@ impl mir::Expression { )) } mir::ExprKind::Accessed(expression, type_kind, field) => { - let struct_val = expression.codegen(scope, &state.load(false)).unwrap(); + let struct_val = expression.codegen(scope, &state.load(false))?.unwrap(); let TypeKind::CodegenPtr(inner) = &struct_val.1 else { panic!("tried accessing non-pointer"); @@ -996,7 +1031,12 @@ impl mir::Expression { } mir::ExprKind::Struct(name, items) => { let type_key = CustomTypeKey(name.clone(), scope.module_id); - let struct_ty = Type::CustomType(*scope.type_values.get(&type_key)?); + let struct_ty = Type::CustomType({ + let Some(a) = scope.type_values.get(&type_key) else { + return Ok(None); + }; + *a + }); let load_n = format!("{}.load", name); @@ -1015,7 +1055,7 @@ impl mir::Expression { .build_named(gep_n, Instr::GetStructElemPtr(struct_ptr, i as u32)) .unwrap() .maybe_location(&mut scope.block, location); - if let Some(val) = exp.codegen(scope, state) { + if let Some(val) = exp.codegen(scope, state)? { scope .block .build_named(store_n, Instr::Store(elem_ptr, val.instr())) @@ -1101,6 +1141,7 @@ impl mir::Expression { } mir::ExprKind::CastTo(expression, type_kind) => { let val = expression.codegen(scope, state)?; + let Some(val) = val else { return Ok(None) }; if val.1 == *type_kind { Some(val) @@ -1161,13 +1202,17 @@ impl mir::Expression { if let Some(value) = &value { value.instr().maybe_location(&mut scope.block, location); } - value + Ok(value) } } impl mir::IfExpression { - fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, state: &State) -> Option { - let condition = self.0.codegen(scope, state).unwrap(); + fn codegen<'ctx, 'a>( + &self, + scope: &mut Scope<'ctx, 'a>, + state: &State, + ) -> Result, ErrorKind> { + let condition = self.0.codegen(scope, state)?.unwrap(); // Create blocks let mut then_b = scope.function.ir.block("then"); @@ -1199,7 +1244,7 @@ impl mir::IfExpression { // Generate then-block content let mut then_scope = scope.with_block(then_b); - let then_res = self.1.codegen(&mut then_scope, state); + let then_res = self.1.codegen(&mut then_scope, state)?; then_scope.block.terminate(Term::Br(after_bb)).ok(); let else_res = if let Some(else_expr) = self.2.as_ref() { @@ -1210,7 +1255,7 @@ impl mir::IfExpression { .terminate(Term::CondBr(condition.instr(), then_bb, else_bb)) .unwrap(); - let opt = else_expr.codegen(&mut else_scope, state); + let opt = else_expr.codegen(&mut else_scope, state)?; else_scope.block.terminate(Term::Br(after_bb)).ok(); @@ -1232,7 +1277,7 @@ impl mir::IfExpression { scope.swap_block(after_b); if then_res.is_none() && else_res.is_none() { - None + Ok(None) } else { let mut incoming = Vec::from(then_res.as_slice()); incoming.extend(else_res.clone()); @@ -1260,7 +1305,7 @@ impl mir::IfExpression { (Mutable(_), Mutable(_)) => StackValue(Mutable(instr), lhs_val.1), }, }; - Some(value) + Ok(Some(value)) } } } diff --git a/reid/src/error_raporting.rs b/reid/src/error_raporting.rs index 1a864bc..1d3852a 100644 --- a/reid/src/error_raporting.rs +++ b/reid/src/error_raporting.rs @@ -4,6 +4,7 @@ use std::{ }; use crate::{ + codegen, lexer::{self, Cursor, FullToken, Position}, mir::{self, pass, Metadata, SourceModuleId}, token_stream::{self, TokenRange}, @@ -30,6 +31,8 @@ pub enum ErrorKind { TypeInferenceError(#[source] mir::pass::Error), #[error("{}{}", label("(Linker) "), .0.kind)] LinkerError(#[from] mir::pass::Error), + #[error("{}{}", label("(Codegen) "), .0)] + CodegenError(#[from] codegen::ErrorKind), } impl ErrorKind { @@ -50,6 +53,9 @@ impl ErrorKind { ErrorKind::TypeCheckError(error) => error.metadata, ErrorKind::TypeInferenceError(error) => error.metadata, ErrorKind::LinkerError(error) => error.metadata, + ErrorKind::CodegenError(error) => match error { + codegen::ErrorKind::Null => Default::default(), + }, } } } @@ -155,7 +161,7 @@ impl ReidError { }) } - pub fn from_kind(errors: Vec, map: ErrorModules) -> ReidError { + pub fn from_kind(errors: Vec, map: ErrorModules) -> ReidError { ReidError { map, errors } } } diff --git a/reid/src/lib.rs b/reid/src/lib.rs index c1de2cb..56492a7 100644 --- a/reid/src/lib.rs +++ b/reid/src/lib.rs @@ -137,7 +137,7 @@ pub fn perform_all_passes<'map>( dbg!(&state); if !state.errors.is_empty() { - return Err(ReidError::from_kind::<()>( + return Err(ReidError::from_kind( state.errors.iter().map(|e| e.clone().into()).collect(), module_map.clone(), )); @@ -157,7 +157,7 @@ pub fn perform_all_passes<'map>( dbg!(&state); if !state.errors.is_empty() { - return Err(ReidError::from_kind::<()>( + return Err(ReidError::from_kind( state .errors .iter() @@ -177,7 +177,7 @@ pub fn perform_all_passes<'map>( dbg!(&state); if !state.errors.is_empty() { - return Err(ReidError::from_kind::<()>( + return Err(ReidError::from_kind( state .errors .iter() @@ -214,7 +214,10 @@ pub fn compile_and_pass<'map>( println!("{}", &mir_context); let mut context = Context::new(format!("Reid ({})", env!("CARGO_PKG_VERSION"))); - let codegen_modules = mir_context.codegen(&mut context); + let codegen_modules = match mir_context.codegen(&mut context) { + Ok(modules) => modules, + Err(e) => Err(ReidError::from_kind(vec![e.into()], module_map.clone()))?, + }; #[cfg(debug_assertions)] println!("{}", &codegen_modules.context);