mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 23:31:12 +00:00
make it work
This commit is contained in:
parent
5e1077bf3e
commit
e274976c6a
14 changed files with 158 additions and 26 deletions
|
@ -5551,7 +5551,12 @@ fn substitute_in_expr<'a>(
|
|||
None => None,
|
||||
},
|
||||
|
||||
CoerceToTagId { structure, tag_id, index, union_layout } => match substitute(subs, *structure) {
|
||||
CoerceToTagId {
|
||||
structure,
|
||||
tag_id,
|
||||
index,
|
||||
union_layout,
|
||||
} => match substitute(subs, *structure) {
|
||||
Some(structure) => Some(CoerceToTagId {
|
||||
structure,
|
||||
tag_id: *tag_id,
|
||||
|
@ -5620,7 +5625,7 @@ fn store_pattern_help<'a>(
|
|||
|
||||
let wrapped = Wrapped::from_layout(&layout);
|
||||
|
||||
return store_tag_pattern(
|
||||
return store_newtype_pattern(
|
||||
env,
|
||||
procs,
|
||||
layout_cache,
|
||||
|
@ -5632,7 +5637,10 @@ fn store_pattern_help<'a>(
|
|||
);
|
||||
}
|
||||
AppliedTag {
|
||||
arguments, layout, ..
|
||||
arguments,
|
||||
layout,
|
||||
tag_id,
|
||||
..
|
||||
} => {
|
||||
let union_layout = Layout::Union(*layout);
|
||||
let wrapped = Wrapped::from_layout(&union_layout);
|
||||
|
@ -5642,9 +5650,10 @@ fn store_pattern_help<'a>(
|
|||
procs,
|
||||
layout_cache,
|
||||
outer_symbol,
|
||||
&union_layout,
|
||||
*layout,
|
||||
&arguments,
|
||||
wrapped,
|
||||
*tag_id,
|
||||
stmt,
|
||||
);
|
||||
}
|
||||
|
@ -5682,6 +5691,100 @@ fn store_pattern_help<'a>(
|
|||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn store_tag_pattern<'a>(
|
||||
env: &mut Env<'a, '_>,
|
||||
procs: &mut Procs<'a>,
|
||||
layout_cache: &mut LayoutCache<'a>,
|
||||
structure: Symbol,
|
||||
union_layout: UnionLayout<'a>,
|
||||
arguments: &[(Pattern<'a>, Layout<'a>)],
|
||||
wrapped: Wrapped,
|
||||
tag_id: u8,
|
||||
mut stmt: Stmt<'a>,
|
||||
) -> StorePattern<'a> {
|
||||
use Pattern::*;
|
||||
|
||||
let write_tag = wrapped == Wrapped::MultiTagUnion;
|
||||
|
||||
let mut arg_layouts = Vec::with_capacity_in(arguments.len(), env.arena);
|
||||
let mut is_productive = false;
|
||||
|
||||
if write_tag {
|
||||
// add an element for the tag discriminant
|
||||
arg_layouts.push(Layout::Builtin(TAG_SIZE));
|
||||
}
|
||||
|
||||
for (_, layout) in arguments {
|
||||
arg_layouts.push(*layout);
|
||||
}
|
||||
|
||||
for (index, (argument, arg_layout)) in arguments.iter().enumerate().rev() {
|
||||
let index = if write_tag { index + 1 } else { index };
|
||||
|
||||
let mut arg_layout = *arg_layout;
|
||||
|
||||
if let Layout::RecursivePointer = arg_layout {
|
||||
arg_layout = Layout::Union(union_layout);
|
||||
}
|
||||
|
||||
let load = Expr::CoerceToTagId {
|
||||
index: index as u64,
|
||||
structure,
|
||||
tag_id,
|
||||
union_layout,
|
||||
};
|
||||
|
||||
// let load = Expr::AccessAtIndex {
|
||||
// wrapped,
|
||||
// index: index as u64,
|
||||
// field_layouts: arg_layouts.clone().into_bump_slice(),
|
||||
// structure,
|
||||
// };
|
||||
|
||||
match argument {
|
||||
Identifier(symbol) => {
|
||||
// store immediately in the given symbol
|
||||
stmt = Stmt::Let(*symbol, load, arg_layout, env.arena.alloc(stmt));
|
||||
is_productive = true;
|
||||
}
|
||||
Underscore => {
|
||||
// ignore
|
||||
}
|
||||
IntLiteral(_)
|
||||
| FloatLiteral(_)
|
||||
| EnumLiteral { .. }
|
||||
| BitLiteral { .. }
|
||||
| StrLiteral(_) => {}
|
||||
_ => {
|
||||
// store the field in a symbol, and continue matching on it
|
||||
let symbol = env.unique_symbol();
|
||||
|
||||
// first recurse, continuing to unpack symbol
|
||||
match store_pattern_help(env, procs, layout_cache, argument, symbol, stmt) {
|
||||
StorePattern::Productive(new) => {
|
||||
is_productive = true;
|
||||
stmt = new;
|
||||
// only if we bind one of its (sub)fields to a used name should we
|
||||
// extract the field
|
||||
stmt = Stmt::Let(symbol, load, arg_layout, env.arena.alloc(stmt));
|
||||
}
|
||||
StorePattern::NotProductive(new) => {
|
||||
// do nothing
|
||||
stmt = new;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if is_productive {
|
||||
StorePattern::Productive(stmt)
|
||||
} else {
|
||||
StorePattern::NotProductive(stmt)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn store_newtype_pattern<'a>(
|
||||
env: &mut Env<'a, '_>,
|
||||
procs: &mut Procs<'a>,
|
||||
layout_cache: &mut LayoutCache<'a>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue