mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 07:41:12 +00:00
extract optional record field default assignments
This commit is contained in:
parent
f8e04619b8
commit
40b514a26d
1 changed files with 37 additions and 22 deletions
|
@ -5487,12 +5487,27 @@ pub struct WhenBranch<'a> {
|
||||||
pub guard: Option<Stmt<'a>>,
|
pub guard: Option<Stmt<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_can_pattern<'a>(
|
fn from_can_pattern<'a>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
can_pattern: &roc_can::pattern::Pattern,
|
can_pattern: &roc_can::pattern::Pattern,
|
||||||
|
// ) -> Result<(Pattern<'a>, &'a [(Symbol, Layout<'a>, roc_can::expr::Expr)]), RuntimeError> {
|
||||||
|
) -> Result<Pattern<'a>, RuntimeError> {
|
||||||
|
let mut assignments = Vec::new_in(env.arena);
|
||||||
|
let pattern = from_can_pattern_help(env, layout_cache, can_pattern, &mut assignments)?;
|
||||||
|
|
||||||
|
// Ok((pattern, assignments.into_bump_slice()))
|
||||||
|
Ok(pattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_can_pattern_help<'a>(
|
||||||
|
env: &mut Env<'a, '_>,
|
||||||
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
|
can_pattern: &roc_can::pattern::Pattern,
|
||||||
|
assignments: &mut Vec<'a, (Symbol, Layout<'a>, roc_can::expr::Expr)>,
|
||||||
) -> Result<Pattern<'a>, RuntimeError> {
|
) -> Result<Pattern<'a>, RuntimeError> {
|
||||||
use roc_can::pattern::Pattern::*;
|
use roc_can::pattern::Pattern::*;
|
||||||
|
|
||||||
match can_pattern {
|
match can_pattern {
|
||||||
Underscore => Ok(Pattern::Underscore),
|
Underscore => Ok(Pattern::Underscore),
|
||||||
Identifier(symbol) => Ok(Pattern::Identifier(*symbol)),
|
Identifier(symbol) => Ok(Pattern::Identifier(*symbol)),
|
||||||
|
@ -5614,7 +5629,7 @@ pub fn from_can_pattern<'a>(
|
||||||
let mut mono_args = Vec::with_capacity_in(arguments.len(), env.arena);
|
let mut mono_args = Vec::with_capacity_in(arguments.len(), env.arena);
|
||||||
for ((_, loc_pat), layout) in arguments.iter().zip(field_layouts.iter()) {
|
for ((_, loc_pat), layout) in arguments.iter().zip(field_layouts.iter()) {
|
||||||
mono_args.push((
|
mono_args.push((
|
||||||
from_can_pattern(env, layout_cache, &loc_pat.value)?,
|
from_can_pattern_help(env, layout_cache, &loc_pat.value, assignments)?,
|
||||||
layout.clone(),
|
layout.clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -5674,7 +5689,7 @@ pub fn from_can_pattern<'a>(
|
||||||
let it = argument_layouts[1..].iter();
|
let it = argument_layouts[1..].iter();
|
||||||
for ((_, loc_pat), layout) in arguments.iter().zip(it) {
|
for ((_, loc_pat), layout) in arguments.iter().zip(it) {
|
||||||
mono_args.push((
|
mono_args.push((
|
||||||
from_can_pattern(env, layout_cache, &loc_pat.value)?,
|
from_can_pattern_help(env, layout_cache, &loc_pat.value, assignments)?,
|
||||||
layout.clone(),
|
layout.clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -5738,6 +5753,7 @@ pub fn from_can_pattern<'a>(
|
||||||
layout_cache,
|
layout_cache,
|
||||||
&destruct.value,
|
&destruct.value,
|
||||||
field_layout.clone(),
|
field_layout.clone(),
|
||||||
|
assignments,
|
||||||
)?);
|
)?);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -5761,22 +5777,20 @@ pub fn from_can_pattern<'a>(
|
||||||
match destructs_by_label.remove(&label) {
|
match destructs_by_label.remove(&label) {
|
||||||
Some(destruct) => {
|
Some(destruct) => {
|
||||||
// this field is destructured by the pattern
|
// this field is destructured by the pattern
|
||||||
mono_destructs.push(RecordDestruct {
|
match &destruct.value.typ {
|
||||||
label: destruct.value.label.clone(),
|
|
||||||
symbol: destruct.value.symbol,
|
|
||||||
layout: field_layout,
|
|
||||||
variable,
|
|
||||||
typ: match &destruct.value.typ {
|
|
||||||
roc_can::pattern::DestructType::Optional(_, loc_expr) => {
|
roc_can::pattern::DestructType::Optional(_, loc_expr) => {
|
||||||
// if we reach this stage, the optional field is not present
|
// if we reach this stage, the optional field is not present
|
||||||
// so use the default
|
// so we push the default assignment into the branch
|
||||||
DestructType::Optional(loc_expr.value.clone())
|
assignments.push((
|
||||||
|
destruct.value.symbol,
|
||||||
|
field_layout,
|
||||||
|
loc_expr.value.clone(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
_ => unreachable!(
|
_ => unreachable!(
|
||||||
"only optional destructs can be optional fields"
|
"only optional destructs can be optional fields"
|
||||||
),
|
),
|
||||||
},
|
};
|
||||||
});
|
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// this field is not destructured by the pattern
|
// this field is not destructured by the pattern
|
||||||
|
@ -5830,6 +5844,7 @@ fn from_can_record_destruct<'a>(
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
can_rd: &roc_can::pattern::RecordDestruct,
|
can_rd: &roc_can::pattern::RecordDestruct,
|
||||||
field_layout: Layout<'a>,
|
field_layout: Layout<'a>,
|
||||||
|
assignments: &mut Vec<'a, (Symbol, Layout<'a>, roc_can::expr::Expr)>,
|
||||||
) -> Result<RecordDestruct<'a>, RuntimeError> {
|
) -> Result<RecordDestruct<'a>, RuntimeError> {
|
||||||
Ok(RecordDestruct {
|
Ok(RecordDestruct {
|
||||||
label: can_rd.label.clone(),
|
label: can_rd.label.clone(),
|
||||||
|
@ -5843,9 +5858,9 @@ fn from_can_record_destruct<'a>(
|
||||||
// DestructType::Optional(loc_expr.value.clone())
|
// DestructType::Optional(loc_expr.value.clone())
|
||||||
DestructType::Required
|
DestructType::Required
|
||||||
}
|
}
|
||||||
roc_can::pattern::DestructType::Guard(_, loc_pattern) => {
|
roc_can::pattern::DestructType::Guard(_, loc_pattern) => DestructType::Guard(
|
||||||
DestructType::Guard(from_can_pattern(env, layout_cache, &loc_pattern.value)?)
|
from_can_pattern_help(env, layout_cache, &loc_pattern.value, assignments)?,
|
||||||
}
|
),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue