From f7978d13b7e87e6dab4197215a50dee4958d6632 Mon Sep 17 00:00:00 2001 From: Folkert Date: Fri, 28 Feb 2020 23:39:00 +0100 Subject: [PATCH] convert Bool into a SendType equivalent --- src/constrain/module.rs | 31 ++++++++++++++++++++++++++++-- src/solve.rs | 42 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/constrain/module.rs b/src/constrain/module.rs index 541b50e96b..9e1bf8763e 100644 --- a/src/constrain/module.rs +++ b/src/constrain/module.rs @@ -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, body_con: Constraint, diff --git a/src/solve.rs b/src/solve.rs index 103ec48966..c53c57a988 100644 --- a/src/solve.rs +++ b/src/solve.rs @@ -51,12 +51,32 @@ pub enum SolvedType { Alias(Symbol, Vec<(Lowercase, SolvedType)>, Box), /// a boolean algebra Bool - Boolean(boolean_algebra::Bool), + Boolean(SolvedAtom, Vec), /// 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, 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), } }