convert Bool into a SendType equivalent

This commit is contained in:
Folkert 2020-02-28 23:39:00 +01:00
parent a55e29e6a0
commit f7978d13b7
2 changed files with 68 additions and 5 deletions

View File

@ -5,10 +5,11 @@ use crate::collections::{ImMap, MutMap, SendMap};
use crate::constrain::expr::constrain_decls;
use crate::module::symbol::{ModuleId, Symbol};
use crate::region::Located;
use crate::solve::{BuiltinAlias, SolvedType};
use crate::solve::{BuiltinAlias, SolvedAtom, SolvedType};
use crate::subs::{VarId, VarStore, Variable};
use crate::types::{Alias, Constraint, LetConstraint, Type};
use crate::uniqueness;
use crate::uniqueness::boolean_algebra::{Atom, Bool};
#[inline(always)]
pub fn constrain_module(
@ -239,7 +240,16 @@ pub fn to_type(solved_type: &SolvedType, free_vars: &mut FreeVars, var_store: &V
Box::new(to_type(ext, free_vars, var_store)),
)
}
Boolean(val) => Type::Boolean(val.clone()),
Boolean(solved_free, solved_rest) => {
let free = to_atom(solved_free, free_vars, var_store);
let mut rest = Vec::with_capacity(solved_rest.len());
for solved_atom in solved_rest {
rest.push(to_atom(solved_atom, free_vars, var_store));
}
Type::Boolean(Bool::from_parts(free, rest))
}
Alias(symbol, solved_type_variables, solved_actual) => {
let mut type_variables = Vec::with_capacity(solved_type_variables.len());
@ -258,6 +268,23 @@ pub fn to_type(solved_type: &SolvedType, free_vars: &mut FreeVars, var_store: &V
}
}
pub fn to_atom(solved_atom: &SolvedAtom, free_vars: &mut FreeVars, var_store: &VarStore) -> Atom {
match solved_atom {
SolvedAtom::Zero => Atom::Zero,
SolvedAtom::One => Atom::One,
SolvedAtom::Variable(var_id) => {
if let Some(var) = free_vars.unnamed_vars.get(&var_id) {
Atom::Variable(*var)
} else {
let var = var_store.fresh();
free_vars.unnamed_vars.insert(*var_id, var);
Atom::Variable(var)
}
}
}
}
pub fn constrain_imported_aliases(
aliases: MutMap<Symbol, Alias>,
body_con: Constraint,

View File

@ -51,12 +51,32 @@ pub enum SolvedType {
Alias(Symbol, Vec<(Lowercase, SolvedType)>, Box<SolvedType>),
/// a boolean algebra Bool
Boolean(boolean_algebra::Bool),
Boolean(SolvedAtom, Vec<SolvedAtom>),
/// A type error
Error,
}
#[derive(Debug, Clone, PartialEq)]
pub enum SolvedAtom {
Zero,
One,
Variable(VarId),
}
impl SolvedAtom {
pub fn from_atom(atom: boolean_algebra::Atom) -> Self {
use boolean_algebra::Atom::*;
// NOTE we blindly trust that `var` is a root and has a FlexVar as content
match atom {
Zero => SolvedAtom::Zero,
One => SolvedAtom::One,
Variable(var) => SolvedAtom::Variable(VarId::from_var(var)),
}
}
}
impl SolvedType {
pub fn new(solved_subs: &Solved<Subs>, var: Variable) -> Self {
Self::from_var(solved_subs.inner(), var)
@ -152,7 +172,15 @@ impl SolvedType {
SolvedType::Alias(symbol, solved_args, Box::new(solved_type))
}
Boolean(val) => SolvedType::Boolean(val),
Boolean(val) => {
let free = SolvedAtom::from_atom(val.0);
let mut rest = Vec::with_capacity(val.1.len());
for atom in val.1 {
rest.push(SolvedAtom::from_atom(atom));
}
SolvedType::Boolean(free, rest)
}
Variable(var) => Self::from_var(solved_subs.inner(), var),
}
}
@ -254,7 +282,15 @@ impl SolvedType {
}
EmptyRecord => SolvedType::EmptyRecord,
EmptyTagUnion => SolvedType::EmptyTagUnion,
Boolean(val) => SolvedType::Boolean(val),
Boolean(val) => {
let free = SolvedAtom::from_atom(val.0);
let mut rest = Vec::with_capacity(val.1.len());
for atom in val.1 {
rest.push(SolvedAtom::from_atom(atom));
}
SolvedType::Boolean(free, rest)
}
Erroneous(problem) => SolvedType::Erroneous(problem),
}
}