get tests working again

This commit is contained in:
Folkert 2020-09-06 00:26:41 +02:00
parent c1fdd0ea7b
commit ceb938c9af
7 changed files with 424 additions and 111 deletions

View file

@ -1,5 +1,7 @@
use crate::exhaustive::{Ctor, RenderAs, TagId, Union};
use crate::ir::{DestructType, Env, Expr, JoinPointId, Literal, Param, Pattern, Procs, Stmt};
use crate::ir::{
DestructType, Env, Expr, JoinPointId, Literal, Param, Pattern, Procs, Stmt, Wrapped,
};
use crate::layout::{Builtin, Layout, LayoutCache};
use roc_collections::all::{MutMap, MutSet};
use roc_module::ident::TagName;
@ -569,6 +571,7 @@ fn to_relevant_branch_help<'a>(
tag_name,
arguments,
union,
layout,
..
} => {
match test {
@ -577,39 +580,51 @@ fn to_relevant_branch_help<'a>(
tag_id,
..
} if &tag_name == test_name => {
// Theory: Unbox doesn't have any value for us
if arguments.len() == 1 && union.alternatives.len() == 1 {
let arg = arguments[0].clone();
{
start.push((Path::Unbox(Box::new(path.clone())), guard, arg.0));
start.extend(end);
}
} else if union.alternatives.len() == 1 {
todo!("this should need a special index, right?")
} else {
let sub_positions =
arguments
.into_iter()
.enumerate()
.map(|(index, (pattern, _))| {
(
Path::Index {
index: index as u64,
tag_id: *tag_id,
path: Box::new(path.clone()),
match Wrapped::opt_from_layout(&layout) {
None => todo!(),
Some(wrapped) => {
match wrapped {
Wrapped::SingleElementRecord => {
// Theory: Unbox doesn't have any value for us
let arg = arguments[0].clone();
{
start.push((
Path::Unbox(Box::new(path.clone())),
guard,
arg.0,
));
start.extend(end);
}
}
Wrapped::RecordOrSingleTagUnion => {
todo!("this should need a special index, right?")
}
Wrapped::MultiTagUnion => {
let sub_positions = arguments.into_iter().enumerate().map(
|(index, (pattern, _))| {
dbg!(index, &pattern, &tag_name, tag_id);
(
Path::Index {
index: 1 + index as u64,
tag_id: *tag_id,
path: Box::new(path.clone()),
},
Guard::NoGuard,
pattern,
)
},
Guard::NoGuard,
pattern,
)
});
start.extend(sub_positions);
start.extend(end);
}
);
start.extend(sub_positions);
start.extend(end);
}
}
Some(Branch {
goal: branch.goal,
patterns: start,
})
Some(Branch {
goal: branch.goal,
patterns: start,
})
}
}
}
_ => None,
}
@ -940,6 +955,7 @@ fn path_to_expr_help2<'a>(
let mut stores = bumpalo::collections::Vec::new_in(env.arena);
loop {
dbg!(&layout);
match path {
Path::Unbox(unboxed) => {
path = unboxed;
@ -950,32 +966,61 @@ fn path_to_expr_help2<'a>(
index,
tag_id,
path: nested,
} => {
let (is_unwrapped, field_layouts) = match layout.clone() {
Layout::Union(layouts) => {
(layouts.is_empty(), layouts[*tag_id as usize].to_vec())
}
Layout::Struct(layouts) => (true, layouts.to_vec()),
other => (true, vec![other]),
};
} => match Wrapped::opt_from_layout(&layout) {
None => {
// this MUST be an index into a single-element (hence unwrapped) record
debug_assert!(*index < field_layouts.len() as u64);
debug_assert_eq!(*index, 0);
debug_assert_eq!(*tag_id, 0);
debug_assert_eq!(**nested, Path::Empty);
let inner_layout = field_layouts[*index as usize].clone();
let field_layouts = vec![layout.clone()];
let inner_expr = Expr::AccessAtIndex {
index: *index,
field_layouts: env.arena.alloc(field_layouts),
structure: symbol,
is_unwrapped,
};
debug_assert!(*index < field_layouts.len() as u64);
symbol = env.unique_symbol();
stores.push((symbol, inner_layout.clone(), inner_expr));
let inner_layout = field_layouts[*index as usize].clone();
println!("loc 5 {}", symbol);
let inner_expr = Expr::AccessAtIndex {
index: *index,
field_layouts: env.arena.alloc(field_layouts),
structure: symbol,
wrapped: Wrapped::SingleElementRecord,
};
layout = inner_layout;
path = nested;
}
symbol = env.unique_symbol();
stores.push((symbol, inner_layout.clone(), inner_expr));
break;
}
Some(wrapped) => {
let field_layouts = match layout {
Layout::Union(layouts) | Layout::RecursiveUnion(layouts) => {
layouts[*tag_id as usize].to_vec()
}
Layout::Struct(layouts) => layouts.to_vec(),
other => vec![other.clone()],
};
dbg!(&field_layouts, tag_id, index);
debug_assert!(*index < field_layouts.len() as u64);
let inner_layout = field_layouts[*index as usize].clone();
println!("loc 6 {}", symbol);
let inner_expr = Expr::AccessAtIndex {
index: *index,
field_layouts: env.arena.alloc(field_layouts),
structure: symbol,
wrapped,
};
symbol = env.unique_symbol();
stores.push((symbol, inner_layout.clone(), inner_expr));
layout = inner_layout;
path = nested;
}
},
}
}
@ -989,6 +1034,9 @@ fn test_to_equality<'a>(
path: &Path,
test: Test<'a>,
) -> (StoresVec<'a>, Symbol, Symbol, Layout<'a>) {
let (rhs_symbol, mut stores, _layout) =
path_to_expr_help2(env, cond_symbol, &path, cond_layout.clone());
match test {
Test::IsCtor {
tag_id,
@ -996,6 +1044,7 @@ fn test_to_equality<'a>(
arguments,
..
} => {
let path_symbol = rhs_symbol;
// the IsCtor check should never be generated for tag unions of size 1
// (e.g. record pattern guard matches)
debug_assert!(union.alternatives.len() > 1);
@ -1011,21 +1060,21 @@ fn test_to_equality<'a>(
for (_, layout) in arguments {
field_layouts.push(layout);
}
let field_layouts = field_layouts.into_bump_slice();
println!("loc 7 {}", path_symbol);
let rhs = Expr::AccessAtIndex {
index: 0,
field_layouts: field_layouts.into_bump_slice(),
structure: cond_symbol,
is_unwrapped: union.alternatives.len() == 1,
field_layouts,
structure: path_symbol,
wrapped: Wrapped::MultiTagUnion,
};
let lhs_symbol = env.unique_symbol();
let rhs_symbol = env.unique_symbol();
let mut stores = bumpalo::collections::Vec::with_capacity_in(2, env.arena);
stores.push((lhs_symbol, Layout::Builtin(Builtin::Int64), lhs));
stores.push((rhs_symbol, Layout::Builtin(Builtin::Int64), rhs));
stores.insert(0, (rhs_symbol, Layout::Builtin(Builtin::Int64), rhs));
(
stores,
@ -1037,7 +1086,6 @@ fn test_to_equality<'a>(
Test::IsInt(test_int) => {
let lhs = Expr::Literal(Literal::Int(test_int));
let lhs_symbol = env.unique_symbol();
let (mut stores, rhs_symbol) = path_to_expr(env, cond_symbol, &path, &cond_layout);
stores.push((lhs_symbol, Layout::Builtin(Builtin::Int64), lhs));
(
@ -1053,7 +1101,6 @@ fn test_to_equality<'a>(
let test_float = f64::from_bits(test_int as u64);
let lhs = Expr::Literal(Literal::Float(test_float));
let lhs_symbol = env.unique_symbol();
let (mut stores, rhs_symbol) = path_to_expr(env, cond_symbol, &path, &cond_layout);
stores.push((lhs_symbol, Layout::Builtin(Builtin::Float64), lhs));
(
@ -1069,7 +1116,6 @@ fn test_to_equality<'a>(
} => {
let lhs = Expr::Literal(Literal::Byte(test_byte));
let lhs_symbol = env.unique_symbol();
let (mut stores, rhs_symbol) = path_to_expr(env, cond_symbol, &path, &cond_layout);
stores.push((lhs_symbol, Layout::Builtin(Builtin::Int8), lhs));
(
@ -1083,7 +1129,6 @@ fn test_to_equality<'a>(
Test::IsBit(test_bit) => {
let lhs = Expr::Literal(Literal::Bool(test_bit));
let lhs_symbol = env.unique_symbol();
let (mut stores, rhs_symbol) = path_to_expr(env, cond_symbol, &path, &cond_layout);
stores.push((lhs_symbol, Layout::Builtin(Builtin::Int1), lhs));
(
@ -1097,7 +1142,6 @@ fn test_to_equality<'a>(
Test::IsStr(test_str) => {
let lhs = Expr::Literal(Literal::Str(env.arena.alloc(test_str)));
let lhs_symbol = env.unique_symbol();
let (mut stores, rhs_symbol) = path_to_expr(env, cond_symbol, &path, &cond_layout);
stores.push((lhs_symbol, Layout::Builtin(Builtin::Str), lhs));