Commit bfe531b5 authored by Daan Sprenkels's avatar Daan Sprenkels
Browse files

infer: nuke remaining polymorphic function code

parent b1324a72
Pipeline #1390 passed with stage
......@@ -2,7 +2,7 @@ use std::cell::{RefCell, RefMut};
use std::fmt;
use std::rc::Rc;
use infer::{FunctionSignature, FunctionType, Type as SPLType};
use infer::Type as SPLType;
use infer::ToSPLType;
use util::Span;
......@@ -187,15 +187,7 @@ impl ToSPLType for FunType {
fn to_spl_type(&self) -> SPLType {
let args = self.args.iter().map(|x| Box::new(x.to_spl_type())).collect();
let ret_type = self.ret.to_spl_type();
let template = FunctionSignature {
args: args,
ret: Box::new(ret_type),
};
let function_type = FunctionType {
template: template,
signatures: Vec::new(),
};
SPLType::Function(function_type)
SPLType::Function(args, Box::new(ret_type))
}
}
......
......@@ -50,92 +50,13 @@ pub enum Type {
List(Box<Type>),
Pair(Box<Type>, Box<Type>),
Bool,
Function(FunctionType),
Function(Vec<Box<Type>>, Box<Type>),
Poly(String), // only used in polymorfic function templates
// Noop: only used to annotate that this type is not relevant, can be used aa
// a placeholder in temporary (short-lived) types
Noop,
}
impl Type {
pub fn is_concrete(&self) -> bool {
match *self {
Type::Variable(usize) => false,
Type::Void => true,
Type::Int => true,
Type::Char => true,
Type::List(ref inner) => inner.is_concrete(),
Type::Pair(ref fst, ref snd) => fst.is_concrete() && snd.is_concrete(),
Type::Bool => true,
Type::Function(_) => false,
Type::Poly(_) => false,
Type::Noop => false,
}
}
pub fn replace_poly(&self, ident: &str, replace_with: Type) -> Type {
match *self {
Type::Poly(ref x) if x == ident => replace_with,
Type::List(ref inner) => Type::List(Box::new(inner.replace_poly(ident, replace_with))),
Type::Pair(ref fst, ref snd) => Type::Pair(
Box::new(fst.replace_poly(ident, replace_with.clone())),
Box::new(snd.replace_poly(ident, replace_with)),
),
_ => self.clone(),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub struct FunctionType {
pub template: FunctionSignature,
pub signatures: Vec<FunctionSignature>,
}
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub struct FunctionSignature {
pub args: Vec<Box<Type>>,
pub ret: Box<Type>,
}
impl FunctionType {
/// `request_signature` will return true if any inference has happened inside this function
/// If it was possible to find a matching signature, this will be returned.
/// If it was not possible to find a matching signature, this function will return (_, None).
/// This does not mean that an error has occurred, if an error occurs in this function,
/// it will panic.
pub fn request_signature(&mut self, act_args: Vec<Box<Type>>, ret: Type) -> Option<FunctionSignature> {
// generate a new signature, given the requested signature
// and add it to self.1 (the list of signatures)
let mut new_sig_args = self.template.args.clone();
let new_sig_ret = self.template.ret.clone();
if new_sig_args.len() != act_args.len() {
panic!("wrong amount of arguments applied to function");
}
for i in 0..new_sig_args.len() {
let (mut sig_arg, mut act_arg) = (*new_sig_args[i].clone(), *act_args[i].clone());
if let Some((x, y, polybinds)) = try_unification(sig_arg, act_arg) {
new_sig_args[i] = Box::new(x);
// we now have to update all following arguments to have the unified poly types
for (name, t) in polybinds {
for j in i..new_sig_args.len() {
let sig_arg = new_sig_args[j].clone();
new_sig_args[j] = Box::new(sig_arg.replace_poly(&name, t.clone()));
}
}
} else {
// we do not have enough information to unify the function type with the
// requested argument types
return None;
}
}
Some(FunctionSignature {
args: new_sig_args,
ret: new_sig_ret,
})
}
}
// unification of free variables and inference
impl ast::SPL {
......@@ -192,9 +113,6 @@ impl ast::VarDecl {
impl ast::FunDecl {
pub fn unify_free_variables(&mut self, spl: &ast::SPL) {
let fun_decl = self.clone();
if let Some(ref mut fun_type) = self.fun_type {
fun_type.unify_free_type_variables(&fun_decl);
}
for vars in self.vars.iter_mut() {
vars.unify_free_variables(spl, None);
}
......@@ -216,13 +134,7 @@ impl ast::FunDecl {
}
impl ast::FunType {
pub fn unify_free_type_variables(&mut self, fun_decl: &ast::FunDecl) {
for (i, arg) in self.args.iter_mut().enumerate() {
if let &mut ast::Type::Ident(ref mut ident) = arg {
ident.unify_free_type_variables(fun_decl, Some(i));
}
}
}
}
impl ast::Stmt {
......@@ -532,19 +444,6 @@ impl ast::Ident {
panic!("referencing undeclared variable `{}`", self)
}
}
pub fn unify_free_type_variables(&mut self, fun_decl: &ast::FunDecl,
until_fun_argument: Option<usize>) {
if let Some(other) = search_fun_environment_type(fun_decl, &self.clone(),
until_fun_argument) {
let other_type = other.spl_type.clone();
if self.spl_type != other_type {
self.spl_type = other.spl_type.clone();
}
} else {
panic!("referencing undeclared type variable `{}`", self)
}
}
}
// epic unification function
......
......@@ -293,15 +293,7 @@ impl Parser {
.map(|_| Box::new(infer::Type::Poly(polyvar_iter.next().unwrap())))
.collect();
let return_type = Box::new(infer::Type::Poly(polyvar_iter.next().unwrap()));
let template = infer::FunctionSignature {
args: arg_spl_types,
ret: return_type
};
let function_type = infer::FunctionType {
template: template,
signatures: Vec::new(),
};
infer::Type::Function(function_type)
infer::Type::Function(arg_spl_types, return_type)
};
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment