Skip to content

fix: enforce consistent evaluation order in emit - #526

Merged
ivov merged 2 commits into
mainfrom
emit-consistent-eval-order
May 28, 2026
Merged

fix: enforce consistent evaluation order in emit#526
ivov merged 2 commits into
mainfrom
emit-consistent-eval-order

Conversation

@ivov

@ivov ivov commented May 28, 2026

Copy link
Copy Markdown
Owner

Lis evaluates expressions left to right, but it was possible for the emitted Go to read an indexed receiver, computed callee, slice bound, or assignment target after a sibling expession had already changed a value it depended on, leading to the wrong slot, fn or ptr being used at runtime. Hence this PR pins those operands into a temp before the sibling runs, so eval order matches the source order.

For example:

fn bump(i: Ref<int>) -> int {
  i.* = 1
  99
}

fn main() {
  let xss = [[10], [20]]
  let mut i = 0
  let ys = xss[i].append(bump(&i))  // i is 0 when xss[i] is chosen
  print(ys[0])                      // 10  (previously printed 20)
}

Source order says xss[i] is chosen while i is still 0, so the append targets xss[0] and ys[0] is 10. Previously the emitted Go ran bump(&i) first, bumping i to 1, so it appended to xss[1] and printed 20. The fix captures xss[i] into a temp before bump runs, so the receiver is locked in at the source-order moment.

@ivov
ivov merged commit 749ada5 into main May 28, 2026
14 checks passed
@ivov ivov mentioned this pull request May 28, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Released in lisette-v0.2.15

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant