mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
get tests working again
This commit is contained in:
parent
c1fdd0ea7b
commit
ceb938c9af
7 changed files with 424 additions and 111 deletions
|
@ -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));
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue