Skip to content

Commit

Permalink
fix: Display function name and body when inlining recursion limit hit (
Browse files Browse the repository at this point in the history
…#6291)

# Description

## Problem\*

Resolves #4828 

## Summary\*

Given a program like this:
```
fn main() {
  main();
}
```

Changed this panic message:

```
Attempted to recur more than 1000 times during function inlining.
```

Into this:
```
Attempted to recur more than 1000 times during inlining function 'main': acir(inline) fn main f0 {
  b0():
    call f0()
    return 
}
```

I included the ACIR to help figure out which function is the culprit, in
case the name is not enough.

## Additional Context

I added a test to show that there is no compilation error or warning for
the example program. It would be nice to issue a warning about
unconditional recursion like Rust does. I'll try to do that in a
followup PR.


## 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.
- [ ] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
  • Loading branch information
aakoshh authored Oct 21, 2024
1 parent d8767b3 commit 33a1e7d
Showing 1 changed file with 27 additions and 2 deletions.
29 changes: 27 additions & 2 deletions compiler/noirc_evaluator/src/ssa/opt/inlining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,13 +291,14 @@ impl InlineContext {
) -> Vec<ValueId> {
self.recursion_level += 1;

let source_function = &ssa.functions[&id];

if self.recursion_level > RECURSION_LIMIT {
panic!(
"Attempted to recur more than {RECURSION_LIMIT} times during function inlining."
"Attempted to recur more than {RECURSION_LIMIT} times during inlining function '{}': {}", source_function.name(), source_function
);
}

let source_function = &ssa.functions[&id];
let mut context = PerFunctionContext::new(self, source_function);

let parameters = source_function.parameters();
Expand Down Expand Up @@ -967,4 +968,28 @@ mod test {
let main = ssa.main();
assert_eq!(main.reachable_blocks().len(), 4);
}

#[test]
#[should_panic(
expected = "Attempted to recur more than 1000 times during inlining function 'main': acir(inline) fn main f0 {"
)]
fn unconditional_recursion() {
// fn main f1 {
// b0():
// call f1()
// return
// }
let main_id = Id::test_new(0);
let mut builder = FunctionBuilder::new("main".into(), main_id);

let main = builder.import_function(main_id);
let results = builder.insert_call(main, Vec::new(), vec![]).to_vec();
builder.terminate_with_return(results);

let ssa = builder.finish();
assert_eq!(ssa.functions.len(), 1);

let inlined = ssa.inline_functions();
assert_eq!(inlined.functions.len(), 0);
}
}

0 comments on commit 33a1e7d

Please sign in to comment.