Merge trunk

This commit is contained in:
Richard Feldman 2020-06-29 19:38:28 -04:00
parent baa3debae2
commit 8c96d12661
26 changed files with 2600 additions and 1093 deletions

View file

@ -4,7 +4,7 @@ use roc_collections::all::{ImMap, MutMap, SendMap};
use roc_module::ident::TagName;
use roc_module::symbol::Symbol;
use roc_region::all::{Located, Region};
use roc_types::boolean_algebra::{self, Atom};
use roc_types::boolean_algebra::{self, Bool};
use roc_types::solved_types::Solved;
use roc_types::subs::{Content, Descriptor, FlatType, Mark, OptVariable, Rank, Subs, Variable};
use roc_types::types::Type::{self, *};
@ -547,7 +547,7 @@ fn type_to_variable(
EmptyTagUnion => Variable::EMPTY_TAG_UNION,
// This case is important for the rank of boolean variables
Boolean(boolean_algebra::Bool(Atom::Variable(var), rest)) if rest.is_empty() => *var,
Boolean(boolean_algebra::Bool::Container(cvar, mvars)) if mvars.is_empty() => *cvar,
Boolean(b) => {
let content = Content::Structure(FlatType::Boolean(b.clone()));
@ -650,6 +650,7 @@ fn type_to_variable(
}
Alias(Symbol::BOOL_BOOL, _, _) => Variable::BOOL,
Alias(symbol, args, alias_type) => {
// TODO cache in uniqueness inference gives problems! all Int's get the same uniqueness var!
// Cache aliases without type arguments. Commonly used aliases like `Int` would otherwise get O(n)
// different variables (once for each occurence). The recursion restriction is required
// for uniqueness types only: recursive aliases "introduce" an unbound uniqueness
@ -666,11 +667,13 @@ fn type_to_variable(
// TODO does caching work at all with uniqueness types? even Int then hides a uniqueness variable
let is_recursive = alias_type.is_recursive();
let no_args = args.is_empty();
/*
if no_args && !is_recursive {
if let Some(var) = cached.get(symbol) {
return *var;
}
}
*/
let mut arg_vars = Vec::with_capacity(args.len());
let mut new_aliases = ImMap::default();
@ -688,7 +691,7 @@ fn type_to_variable(
let result = register(subs, rank, pools, content);
if no_args && !is_recursive {
cached.insert(*symbol, result);
// cached.insert(*symbol, result);
}
result
@ -793,7 +796,30 @@ fn check_for_infinite_type(
_ => circular_error(subs, problems, symbol, &loc_var),
}
}
_ => circular_error(subs, problems, symbol, &loc_var),
Content::Structure(FlatType::Boolean(Bool::Container(_cvar, _mvars))) => {
// We have a loop in boolean attributes. The attributes can be seen as constraints
// too, so if we have
//
// Container( u1, { u2, u3 } )
//
// That means u1 >= u2 and u1 >= u3
//
// Now if u1 occurs in the definition of u2, then that's like saying u1 >= u2 >= u1,
// which can only be true if u1 == u2. So that's what we do with unify.
for var in chain {
if let Content::Structure(FlatType::Boolean(_)) =
subs.get_without_compacting(var).content
{
// this unify just makes new pools. is that bad?
let outcome = unify(subs, recursive, var);
debug_assert!(matches!(outcome, roc_unify::unify::Unified::Success(_)));
}
}
boolean_algebra::flatten(subs, recursive);
}
_other => circular_error(subs, problems, symbol, &loc_var),
}
}
}
@ -1050,9 +1076,11 @@ fn adjust_rank_content(
rank
}
Boolean(b) => {
let mut rank = Rank::toplevel();
for var in b.variables() {
Boolean(Bool::Shared) => Rank::toplevel(),
Boolean(Bool::Container(cvar, mvars)) => {
let mut rank = adjust_rank(subs, young_mark, visit_mark, group_rank, cvar);
for var in mvars {
rank = rank.max(adjust_rank(subs, young_mark, visit_mark, group_rank, var));
}