make things work

This commit is contained in:
Folkert 2021-08-13 11:04:31 +02:00
parent 67182baa81
commit c9040c012e
8 changed files with 156 additions and 62 deletions

View File

@ -7503,7 +7503,8 @@ pub fn num_argument_to_int_or_float(
debug_assert!(args.len() == 1);
// Recurse on the second argument
num_argument_to_int_or_float(subs, ptr_bytes, args[0].1, false)
let var = subs[args.variables().into_iter().next().unwrap()];
num_argument_to_int_or_float(subs, ptr_bytes, var, false)
}
Content::Alias(Symbol::NUM_I128, _, _)
@ -7561,7 +7562,8 @@ pub fn num_argument_to_int_or_float(
debug_assert!(args.len() == 1);
// Recurse on the second argument
num_argument_to_int_or_float(subs, ptr_bytes, args[0].1, true)
let var = subs[args.variables().into_iter().next().unwrap()];
num_argument_to_int_or_float(subs, ptr_bytes, var, true)
}
Content::Alias(Symbol::NUM_FLOAT, _, _) // We default FloatingPoint to F64
| Content::Alias(Symbol::NUM_F64, _, _)

View File

@ -2192,7 +2192,7 @@ fn unwrap_num_tag<'a>(subs: &Subs, var: Variable) -> Result<Layout<'a>, LayoutPr
Content::Alias(Symbol::NUM_INTEGER, args, _) => {
debug_assert!(args.len() == 1);
let (_, precision_var) = args[0];
let precision_var = subs[args.variables().into_iter().next().unwrap()];
let precision = subs.get_content_without_compacting(precision_var);
@ -2227,7 +2227,7 @@ fn unwrap_num_tag<'a>(subs: &Subs, var: Variable) -> Result<Layout<'a>, LayoutPr
Content::Alias(Symbol::NUM_FLOATINGPOINT, args, _) => {
debug_assert!(args.len() == 1);
let (_, precision_var) = args[0];
let precision_var = subs[args.variables().into_iter().next().unwrap()];
let precision = subs.get_content_without_compacting(precision_var);

View File

@ -5,8 +5,8 @@ use roc_module::symbol::Symbol;
use roc_region::all::{Located, Region};
use roc_types::solved_types::Solved;
use roc_types::subs::{
Content, Descriptor, FlatType, Mark, OptVariable, Rank, RecordFields, Subs, SubsIndex,
Variable, VariableSubsSlice,
AliasVariables, Content, Descriptor, FlatType, Mark, OptVariable, Rank, RecordFields, Subs,
SubsIndex, Variable, VariableSubsSlice,
};
use roc_types::types::Type::{self, *};
use roc_types::types::{gather_fields_unsorted_iter, Alias, Category, ErrorType, PatternCategory};
@ -811,6 +811,8 @@ fn type_to_variable(
arg_vars.push((arg.clone(), arg_var));
}
let arg_vars = AliasVariables::insert_into_subs(subs, arg_vars, []);
let alias_var = type_to_variable(subs, rank, pools, cached, alias_type);
let content = Content::Alias(*symbol, arg_vars, alias_var);
@ -831,6 +833,8 @@ fn type_to_variable(
arg_vars.push((arg.clone(), arg_var));
}
let arg_vars = AliasVariables::insert_into_subs(subs, arg_vars, []);
let alias_var = type_to_variable(subs, rank, pools, cached, alias_type);
// unify the actual_var with the result var
@ -1157,8 +1161,9 @@ fn adjust_rank_content(
Alias(_, args, real_var) => {
let mut rank = Rank::toplevel();
for (_, var) in args {
rank = rank.max(adjust_rank(subs, young_mark, visit_mark, group_rank, *var));
for var_index in args.variables() {
let var = subs[var_index];
rank = rank.max(adjust_rank(subs, young_mark, visit_mark, group_rank, var));
}
// from elm-compiler: THEORY: anything in the real_var would be Rank::toplevel()
@ -1312,7 +1317,8 @@ fn instantiate_rigids_help(
}
Alias(_, args, real_type_var) => {
for (_, var) in args.into_iter() {
for var_index in args.variables().into_iter() {
let var = subs[var_index];
instantiate_rigids_help(subs, max_rank, pools, var);
}
@ -1533,13 +1539,20 @@ fn deep_copy_var_help(
copy
}
Alias(symbol, args, real_type_var) => {
let new_args = args
.into_iter()
.map(|(name, var)| (name, deep_copy_var_help(subs, max_rank, pools, var)))
.collect();
Alias(symbol, mut args, real_type_var) => {
let mut new_vars = Vec::with_capacity(args.variables().len());
for var_index in args.variables() {
let var = subs[var_index];
let new_var = deep_copy_var_help(subs, max_rank, pools, var);
new_vars.push(new_var);
}
args.replace_variables(subs, new_vars);
let new_real_type_var = deep_copy_var_help(subs, max_rank, pools, real_type_var);
let new_content = Alias(symbol, new_args, new_real_type_var);
let new_content = Alias(symbol, args, new_real_type_var);
subs.set(copy, make_descriptor(new_content));

View File

@ -198,8 +198,9 @@ fn find_names_needed(
find_names_needed(*rec_var, subs, roots, root_appearances, names_taken);
}
Alias(_symbol, args, _actual) => {
for (_, var) in args {
find_names_needed(*var, subs, roots, root_appearances, names_taken);
for var_index in args.variables() {
let var = subs[var_index];
find_names_needed(var, subs, roots, root_appearances, names_taken);
}
// TODO should we also look in the actual variable?
// find_names_needed(_actual, subs, roots, root_appearances, names_taken);
@ -306,10 +307,13 @@ fn write_content(env: &Env, content: &Content, subs: &Subs, buf: &mut String, pa
Symbol::NUM_NUM => {
debug_assert_eq!(args.len(), 1);
let (_, arg_var) = args
.get(0)
let arg_var_index = args
.variables()
.into_iter()
.next()
.expect("Num was not applied to a type argument!");
let content = subs.get_content_without_compacting(*arg_var);
let arg_var = subs[arg_var_index];
let content = subs.get_content_without_compacting(arg_var);
match &content {
Alias(nested, _, _) => match *nested {
@ -332,11 +336,12 @@ fn write_content(env: &Env, content: &Content, subs: &Subs, buf: &mut String, pa
_ => write_parens!(write_parens, buf, {
write_symbol(env, *symbol, buf);
for (_, var) in args {
for var_index in args.variables() {
let var = subs[var_index];
buf.push(' ');
write_content(
env,
subs.get_content_without_compacting(*var),
subs.get_content_without_compacting(var),
subs,
buf,
Parens::InTypeParam,

View File

@ -352,10 +352,12 @@ impl SolvedType {
Alias(symbol, args, actual_var) => {
let mut new_args = Vec::with_capacity(args.len());
for (arg_name, arg_var) in args {
for (name_index, var_index) in args.named_type_arguments() {
let arg_var = subs[var_index];
new_args.push((
arg_name.clone(),
Self::from_var_help(subs, recursion_vars, *arg_var),
subs[name_index].clone(),
Self::from_var_help(subs, recursion_vars, arg_var),
));
}

View File

@ -9,8 +9,8 @@ use ven_ena::unify::{InPlace, Snapshot, UnificationTable, UnifyKey};
// if your changes cause this number to go down, great!
// please change it to the lower number.
// if it went up, maybe check that the change is really required
static_assertions::assert_eq_size!([u8; 56], Descriptor);
static_assertions::assert_eq_size!([u8; 40], Content);
static_assertions::assert_eq_size!([u8; 48], Descriptor);
static_assertions::assert_eq_size!([u8; 32], Content);
static_assertions::assert_eq_size!([u8; 24], FlatType);
static_assertions::assert_eq_size!([u8; 48], Problem);
@ -543,7 +543,11 @@ impl Subs {
});
subs.set_content(Variable::BOOL, {
Content::Alias(Symbol::BOOL_BOOL, vec![], Variable::BOOL_ENUM)
Content::Alias(
Symbol::BOOL_BOOL,
AliasVariables::default(),
Variable::BOOL_ENUM,
)
});
subs
@ -846,19 +850,21 @@ pub enum Content {
opt_name: Option<Lowercase>,
},
Structure(FlatType),
Alias(Symbol, Vec<(Lowercase, Variable)>, Variable),
Alias(Symbol, AliasVariables, Variable),
Error,
}
struct AliasVariables {
#[derive(Clone, Copy, Debug, Default)]
pub struct AliasVariables {
lowercases_start: u32,
variables_start: u32,
lowercases_len: u16,
variables_len: u16,
}
impl AliasVariables {
pub const fn names(&self) -> SubsSlice<Lowercase> {
SubsSlice::new(self.variables_start, self.variables_len)
SubsSlice::new(self.lowercases_start, self.lowercases_len)
}
pub const fn variables(&self) -> VariableSubsSlice {
@ -867,6 +873,37 @@ impl AliasVariables {
}
}
pub const fn len(&self) -> usize {
self.lowercases_len as usize
}
pub const fn is_empty(&self) -> bool {
self.lowercases_len == 0
}
pub fn replace_variables(
&mut self,
subs: &mut Subs,
variables: impl IntoIterator<Item = Variable>,
) {
let variables_start = subs.variables.len() as u32;
subs.variables.extend(variables);
let variables_len = (subs.variables.len() - variables_start as usize) as u16;
debug_assert_eq!(variables_len, self.variables_len);
self.variables_start = variables_start;
}
pub fn named_type_arguments(
&self,
) -> impl Iterator<Item = (SubsIndex<Lowercase>, SubsIndex<Variable>)> {
let names = self.names();
let vars = self.variables();
names.into_iter().zip(vars.into_iter())
}
pub fn insert_into_subs<I1, I2>(
subs: &mut Subs,
type_arguments: I1,
@ -1481,8 +1518,13 @@ fn occurs(
Alias(_, args, _) => {
let mut new_seen = seen.clone();
new_seen.insert(root_var);
let it = args.iter().map(|(_, var)| var);
short_circuit(subs, root_var, &new_seen, it)
for var_index in args.variables().into_iter() {
let var = subs[var_index];
short_circuit_help(subs, root_var, &new_seen, var)?;
}
Ok(())
}
}
}
@ -1660,9 +1702,11 @@ fn explicit_substitute(
in_var
}
Alias(symbol, mut args, actual) => {
for (_, var) in args.iter_mut() {
*var = explicit_substitute(subs, from, to, *var, seen);
Alias(symbol, args, actual) => {
for index in args.variables().into_iter() {
let var = subs[index];
let new_var = explicit_substitute(subs, from, to, var, seen);
subs[index] = new_var;
}
let new_actual = explicit_substitute(subs, from, to, actual, seen);
@ -1716,9 +1760,12 @@ fn get_var_names(
RigidVar(name) => add_name(subs, 0, name, var, RigidVar, taken_names),
Alias(_, args, _) => args.into_iter().fold(taken_names, |answer, (_, arg_var)| {
get_var_names(subs, arg_var, answer)
}),
Alias(_, args, _) => args
.variables()
.into_iter()
.fold(taken_names, |answer, arg_var| {
get_var_names(subs, subs[arg_var], answer)
}),
Structure(flat_type) => match flat_type {
FlatType::Apply(_, args) => {
args.into_iter().fold(taken_names, |answer, arg_var| {
@ -1916,12 +1963,19 @@ fn content_to_err_type(
}
Alias(symbol, args, aliased_to) => {
let err_args = args
.into_iter()
.map(|(name, var)| (name, var_to_err_type(subs, state, var)))
.collect();
let err_type = var_to_err_type(subs, state, aliased_to);
let mut err_args = Vec::with_capacity(args.names().len());
for (name_index, var_index) in args.named_type_arguments() {
let name = subs[name_index].clone();
let var = subs[var_index];
let arg = var_to_err_type(subs, state, var);
err_args.push((name, arg));
}
ErrorType::Alias(symbol, err_args, Box::new(err_type))
}
@ -2194,8 +2248,9 @@ fn restore_content(subs: &mut Subs, content: &Content) {
Erroneous(_) => (),
},
Alias(_, args, var) => {
for (_, arg_var) in args {
subs.restore(*arg_var);
for var_index in args.variables().into_iter() {
let var = subs[var_index];
subs.restore(var);
}
subs.restore(*var);

View File

@ -3,8 +3,8 @@ use roc_module::ident::{Lowercase, TagName};
use roc_module::symbol::Symbol;
use roc_types::subs::Content::{self, *};
use roc_types::subs::{
Descriptor, FlatType, GetSubsSlice, Mark, OptVariable, RecordFields, Subs, SubsIndex,
SubsSlice, UnionTags, Variable, VariableSubsSlice,
AliasVariables, Descriptor, FlatType, GetSubsSlice, Mark, OptVariable, RecordFields, Subs,
SubsIndex, SubsSlice, UnionTags, Variable, VariableSubsSlice,
};
use roc_types::types::{ErrorType, Mismatch, RecordField};
@ -158,7 +158,7 @@ fn unify_context(subs: &mut Subs, pool: &mut Pool, ctx: Context) -> Outcome {
Structure(flat_type) => {
unify_structure(subs, pool, &ctx, flat_type, &ctx.second_desc.content)
}
Alias(symbol, args, real_var) => unify_alias(subs, pool, &ctx, *symbol, args, *real_var),
Alias(symbol, args, real_var) => unify_alias(subs, pool, &ctx, *symbol, *args, *real_var),
Error => {
// Error propagates. Whatever we're comparing it to doesn't matter!
merge(subs, &ctx, Error)
@ -172,7 +172,7 @@ fn unify_alias(
pool: &mut Pool,
ctx: &Context,
symbol: Symbol,
args: &[(Lowercase, Variable)],
args: AliasVariables,
real_var: Variable,
) -> Outcome {
let other_content = &ctx.second_desc.content;
@ -188,8 +188,15 @@ fn unify_alias(
if symbol == *other_symbol {
if args.len() == other_args.len() {
let mut problems = Vec::new();
for ((_, l_var), (_, r_var)) in args.iter().zip(other_args.iter()) {
problems.extend(unify_pool(subs, pool, *l_var, *r_var));
let it = args
.variables()
.into_iter()
.zip(other_args.variables().into_iter());
for (l, r) in it {
let l_var = subs[l];
let r_var = subs[r];
problems.extend(unify_pool(subs, pool, l_var, r_var));
}
if problems.is_empty() {

View File

@ -10,8 +10,8 @@ use roc_module::symbol::Symbol;
use roc_region::all::{Located, Region};
use roc_types::solved_types::Solved;
use roc_types::subs::{
Content, Descriptor, FlatType, Mark, OptVariable, Rank, RecordFields, Subs, Variable,
VariableSubsSlice,
AliasVariables, Content, Descriptor, FlatType, Mark, OptVariable, Rank, RecordFields, Subs,
Variable, VariableSubsSlice,
};
use roc_types::types::{
gather_fields_unsorted_iter, Alias, Category, ErrorType, PatternCategory, RecordField,
@ -818,6 +818,8 @@ fn type_to_variable<'a>(
new_aliases.insert(arg_str, arg_var);
}
let arg_vars = AliasVariables::insert_into_subs(subs, arg_vars, []);
let alias_var = type_to_variable(arena, mempool, subs, rank, pools, cached, alias_type);
let content = Content::Alias(*symbol, arg_vars, alias_var);
@ -1280,8 +1282,9 @@ fn adjust_rank_content(
Alias(_, args, real_var) => {
let mut rank = Rank::toplevel();
for (_, var) in args {
rank = rank.max(adjust_rank(subs, young_mark, visit_mark, group_rank, *var));
for var_index in args.variables() {
let var = subs[var_index];
rank = rank.max(adjust_rank(subs, young_mark, visit_mark, group_rank, var));
}
// from elm-compiler: THEORY: anything in the real_var would be Rank::toplevel()
@ -1435,7 +1438,8 @@ fn instantiate_rigids_help(
}
Alias(_, args, real_type_var) => {
for (_, var) in args.into_iter() {
for var_index in args.variables() {
let var = subs[var_index];
instantiate_rigids_help(subs, max_rank, pools, var);
}
@ -1656,13 +1660,19 @@ fn deep_copy_var_help(
copy
}
Alias(symbol, args, real_type_var) => {
let new_args = args
.into_iter()
.map(|(name, var)| (name, deep_copy_var_help(subs, max_rank, pools, var)))
.collect();
Alias(symbol, mut args, real_type_var) => {
let mut new_args = Vec::with_capacity(args.variables().len());
for var_index in args.variables() {
let var = subs[var_index];
let new_var = deep_copy_var_help(subs, max_rank, pools, var);
new_args.push(new_var);
}
args.replace_variables(subs, new_args);
let new_real_type_var = deep_copy_var_help(subs, max_rank, pools, real_type_var);
let new_content = Alias(symbol, new_args, new_real_type_var);
let new_content = Alias(symbol, args, new_real_type_var);
subs.set(copy, make_descriptor(new_content));