Skip to content

Commit df73fe2

Browse files
authored
fix: Complete call stacks with no_predicates (#5418)
# Description ## Problem\* Consider the following code: ```rust fn inner<N>(input: Field) { assert_eq(input, 27); } #[no_predicates] fn no_predicates(input: Field) { inner(input) } fn outer_pass_through(input: Field) { no_predicates(input) } fn main(input: Field) { outer_pass_through(input) } ``` This is the call stack with `#[no_predicates]`: ``` ┌─ /mnt/user-data/alvaro/constructor/src/main.nr:23:5 │ 23 │ assert_eq(input, 27); │ -------------------- │ = Call stack: 1. /mnt/user-data/alvaro/constructor/src/main.nr:32:5 2. /mnt/user-data/alvaro/constructor/src/main.nr:28:5 3. /mnt/user-data/alvaro/constructor/src/main.nr:23:5 ``` This is the call stack without `#[no_predicates]`: ``` error: Failed constraint ┌─ /mnt/user-data/alvaro/constructor/src/main.nr:23:5 │ 23 │ assert_eq(input, 27); │ -------------------- │ = Call stack: 1. /mnt/user-data/alvaro/constructor/src/main.nr:35:5 2. /mnt/user-data/alvaro/constructor/src/main.nr:31:5 3. /mnt/user-data/alvaro/constructor/src/main.nr:27:5 4. /mnt/user-data/alvaro/constructor/src/main.nr:23:5 ``` Inlining with no predicates was eating up the `outer_pass_through` call. ## Summary\* The inliner now doesn't assume that there is at most one location in the source call stack. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings.
1 parent bf3a75a commit df73fe2

File tree

1 file changed

+4
-10
lines changed

1 file changed

+4
-10
lines changed

compiler/noirc_evaluator/src/ssa/opt/inlining.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -517,19 +517,13 @@ impl<'function> PerFunctionContext<'function> {
517517
let old_results = self.source_function.dfg.instruction_results(call_id);
518518
let arguments = vecmap(arguments, |arg| self.translate_value(*arg));
519519

520-
let mut call_stack = self.source_function.dfg.get_call_stack(call_id);
521-
let has_location = !call_stack.is_empty();
522-
523-
// Function calls created by the defunctionalization pass will not have source locations
524-
if let Some(location) = call_stack.pop_back() {
525-
self.context.call_stack.push_back(location);
526-
}
520+
let call_stack = self.source_function.dfg.get_call_stack(call_id);
521+
let call_stack_len = call_stack.len();
522+
self.context.call_stack.append(call_stack);
527523

528524
let new_results = self.context.inline_function(ssa, function, &arguments);
529525

530-
if has_location {
531-
self.context.call_stack.pop_back();
532-
}
526+
self.context.call_stack.truncate(self.context.call_stack.len() - call_stack_len);
533527

534528
let new_results = InsertInstructionResult::Results(call_id, &new_results);
535529
Self::insert_new_instruction_results(&mut self.values, old_results, new_results);

0 commit comments

Comments
 (0)