don't special-case a single element record any more in updates

This commit is contained in:
Folkert 2021-09-08 12:59:38 +02:00
parent 2fae415b05
commit 0d1cc3844e
2 changed files with 36 additions and 43 deletions

View file

@ -3739,13 +3739,12 @@ pub fn with_hole<'a>(
debug_assert_eq!(field_layouts.len(), symbols.len()); debug_assert_eq!(field_layouts.len(), symbols.len());
debug_assert_eq!(fields.len(), symbols.len()); debug_assert_eq!(fields.len(), symbols.len());
if symbols.len() == 1 { let expr = Expr::Struct(symbols);
// TODO we can probably special-case this more, skippiing the generation of let mut stmt = Stmt::Let(assigned, expr, record_layout, hole);
// UpdateExisting
let mut stmt = hole.clone();
let what_to_do = &fields[0]; let it = field_layouts.iter().zip(symbols.iter()).zip(fields);
for ((field_layout, symbol), what_to_do) in it {
match what_to_do { match what_to_do {
UpdateExisting(field) => { UpdateExisting(field) => {
stmt = assign_to_symbol( stmt = assign_to_symbol(
@ -3754,50 +3753,21 @@ pub fn with_hole<'a>(
layout_cache, layout_cache,
field.var, field.var,
*field.loc_expr.clone(), *field.loc_expr.clone(),
assigned, *symbol,
stmt, stmt,
); );
} }
CopyExisting(_) => { CopyExisting(index) => {
unreachable!( let access_expr = Expr::StructAtIndex {
r"when a record has just one field and is updated, it must update that one field" structure,
); index,
field_layouts,
};
stmt = Stmt::Let(*symbol, access_expr, *field_layout, arena.alloc(stmt));
} }
} }
stmt
} else {
let expr = Expr::Struct(symbols);
let mut stmt = Stmt::Let(assigned, expr, record_layout, hole);
let it = field_layouts.iter().zip(symbols.iter()).zip(fields);
for ((field_layout, symbol), what_to_do) in it {
match what_to_do {
UpdateExisting(field) => {
stmt = assign_to_symbol(
env,
procs,
layout_cache,
field.var,
*field.loc_expr.clone(),
*symbol,
stmt,
);
}
CopyExisting(index) => {
let access_expr = Expr::StructAtIndex {
structure,
index,
field_layouts,
};
stmt =
Stmt::Let(*symbol, access_expr, *field_layout, arena.alloc(stmt));
}
}
}
stmt
} }
stmt
} }
Closure { Closure {

View file

@ -889,3 +889,26 @@ fn blue_and_absent() {
i64 i64
); );
} }
#[test]
fn update_the_only_field() {
assert_evals_to!(
indoc!(
r#"
Model : { foo : I64 }
model : Model
model = { foo: 3 }
foo = 4
newModel : Model
newModel = { model & foo }
newModel.foo
"#
),
4,
i64
);
}