Make sure that there are no unresolved types left over and the end of pass.

This commit is contained in:
James Harton 2019-04-09 16:06:09 +12:00
parent 1aeeda93fe
commit fc5a796321
5 changed files with 31 additions and 1 deletions

View file

@ -329,6 +329,10 @@ impl Context {
Context::new("Test context") Context::new("Test context")
} }
pub fn types(&self) -> Vec<&Ty> {
self.types.iter().collect()
}
/// Create a type variable of unknown type. /// Create a type variable of unknown type.
/// ///
/// Unresolved types should be removed by typechecking and any remaining /// Unresolved types should be removed by typechecking and any remaining

View file

@ -50,4 +50,5 @@ pub enum ErrorKind {
UnknownVariable, UnknownVariable,
InconsistentBranchTypes, InconsistentBranchTypes,
TypeInferenceFailure, TypeInferenceFailure,
UnknownType,
} }

View file

@ -3,4 +3,5 @@ pub mod clause_return_types;
pub mod desugar_infix; pub mod desugar_infix;
pub mod desugar_unary; pub mod desugar_unary;
pub mod infix_folding; pub mod infix_folding;
pub mod no_unresolved_types_remaining;
pub mod unary_folding; pub mod unary_folding;

View file

@ -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);
}
}

View file

@ -16,7 +16,8 @@ use huia_parser::ast::Term;
use std::fs; use std::fs;
pub fn compile_file(path: &str) -> Context { 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 terms = Term::file(&contents).expect("Unable to parse file");
let mut context = Context::new(path); let mut context = Context::new(path);
let mut builder = ir::builder::Builder::default(); 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::clause_return_types::pass(&mut method, &mut context);
}); });
improvements::no_unresolved_types_remaining::pass(&mut context);
context context
} }