diff --git a/huia-compiler/src/context/mod.rs b/huia-compiler/src/context/mod.rs index 9464adb..30b8b7f 100644 --- a/huia-compiler/src/context/mod.rs +++ b/huia-compiler/src/context/mod.rs @@ -329,6 +329,10 @@ impl Context { Context::new("Test context") } + pub fn types(&self) -> Vec<&Ty> { + self.types.iter().collect() + } + /// Create a type variable of unknown type. /// /// Unresolved types should be removed by typechecking and any remaining diff --git a/huia-compiler/src/error.rs b/huia-compiler/src/error.rs index 1bdec55..2f95334 100644 --- a/huia-compiler/src/error.rs +++ b/huia-compiler/src/error.rs @@ -50,4 +50,5 @@ pub enum ErrorKind { UnknownVariable, InconsistentBranchTypes, TypeInferenceFailure, + UnknownType, } diff --git a/huia-compiler/src/improvements/mod.rs b/huia-compiler/src/improvements/mod.rs index 018d79b..5e433d8 100644 --- a/huia-compiler/src/improvements/mod.rs +++ b/huia-compiler/src/improvements/mod.rs @@ -3,4 +3,5 @@ pub mod clause_return_types; pub mod desugar_infix; pub mod desugar_unary; pub mod infix_folding; +pub mod no_unresolved_types_remaining; pub mod unary_folding; diff --git a/huia-compiler/src/improvements/no_unresolved_types_remaining.rs b/huia-compiler/src/improvements/no_unresolved_types_remaining.rs new file mode 100644 index 0000000..4ffe256 --- /dev/null +++ b/huia-compiler/src/improvements/no_unresolved_types_remaining.rs @@ -0,0 +1,21 @@ +use crate::context::Context; +use crate::error::ErrorKind; + +pub fn pass(context: &mut Context) { + let mut unresolved_types = Vec::default(); + let all_types = context.types(); + for (idx, ty) in all_types.iter().enumerate() { + if ty.is_unresolved() { + let name = match ty.name() { + Some(name_idx) => context.get_string(name_idx).unwrap().to_string(), + None => format!("T{:0>4}", idx), + }; + let message = format!("Unable to resolve type {}", name); + let location = ty.get_location().unwrap().clone(); + unresolved_types.push((message, location)); + } + } + for (message, location) in unresolved_types { + context.compile_error(&message, location, ErrorKind::UnknownType); + } +} diff --git a/huia-compiler/src/lib.rs b/huia-compiler/src/lib.rs index 6582403..f8404b6 100644 --- a/huia-compiler/src/lib.rs +++ b/huia-compiler/src/lib.rs @@ -16,7 +16,8 @@ use huia_parser::ast::Term; use std::fs; pub fn compile_file(path: &str) -> Context { - let contents = fs::read_to_string(path).expect("Unable to open file"); + let contents = fs::read_to_string(path) + .unwrap_or_else(|e| panic!("Unable to open file '{}': {}", path, e)); let terms = Term::file(&contents).expect("Unable to parse file"); let mut context = Context::new(path); let mut builder = ir::builder::Builder::default(); @@ -42,5 +43,7 @@ pub fn compile_file(path: &str) -> Context { improvements::clause_return_types::pass(&mut method, &mut context); }); + improvements::no_unresolved_types_remaining::pass(&mut context); + context }