Skip to content

Commit

Permalink
fix: proper cleanup when breaking from comptime loop on error (#7125)
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite authored Jan 21, 2025
1 parent ed9977a commit bf32a22
Showing 1 changed file with 33 additions and 15 deletions.
48 changes: 33 additions & 15 deletions compiler/noirc_frontend/src/hir/comptime/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1724,50 +1724,68 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
let (end, _) = get_index(self, for_.end_range)?;
let was_in_loop = std::mem::replace(&mut self.in_loop, true);

let mut result = Ok(Value::Unit);

for i in start..end {
self.push_scope();
self.current_scope_mut().insert(for_.identifier.id, make_value(i));

match self.evaluate(for_.block) {
Ok(_) => (),
Err(InterpreterError::Break) => break,
Err(InterpreterError::Continue) => continue,
Err(other) => return Err(other),
}
let must_break = match self.evaluate(for_.block) {
Ok(_) => false,
Err(InterpreterError::Break) => true,
Err(InterpreterError::Continue) => false,
Err(error) => {
result = Err(error);
true
}
};

self.pop_scope();

if must_break {
break;
}
}

self.in_loop = was_in_loop;
Ok(Value::Unit)
result
}

fn evaluate_loop(&mut self, expr: ExprId) -> IResult<Value> {
let was_in_loop = std::mem::replace(&mut self.in_loop, true);
let in_lsp = self.elaborator.interner.is_in_lsp_mode();
let mut counter = 0;
let mut result = Ok(Value::Unit);

loop {
self.push_scope();

match self.evaluate(expr) {
Ok(_) => (),
Err(InterpreterError::Break) => break,
Err(InterpreterError::Continue) => continue,
Err(other) => return Err(other),
}
let must_break = match self.evaluate(expr) {
Ok(_) => false,
Err(InterpreterError::Break) => true,
Err(InterpreterError::Continue) => false,
Err(error) => {
result = Err(error);
true
}
};

self.pop_scope();

if must_break {
break;
}

counter += 1;
if in_lsp && counter == 10_000 {
let location = self.elaborator.interner.expr_location(&expr);
return Err(InterpreterError::LoopHaltedForUiResponsiveness { location });
result = Err(InterpreterError::LoopHaltedForUiResponsiveness { location });
break;
}
}

self.in_loop = was_in_loop;
Ok(Value::Unit)
result
}

fn evaluate_break(&mut self, id: StmtId) -> IResult<Value> {
Expand Down

1 comment on commit bf32a22

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Compilation Time'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.10.

Benchmark suite Current: bf32a22 Previous: ed9977a Ratio
rollup-block-root-single-tx 113 s 85.1 s 1.33

This comment was automatically generated by workflow using github-action-benchmark.

CC: @TomAFrench

Please sign in to comment.