const_assert! loses track of name references inside for loop
- Dominant language
- C++
- Stars
- 1.9k
- Forks
- 283
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 135
Description
**Describe the bug**
When using a `const_assert!` specifically inside a for loop, some references seem to be missing, causing an internal error.
```
INTERNAL: BytecodeEmitter could not find slot or binding for name: result @ ...
stack: 0x55f03400bf7a: std::__u::__variant_detail::__visitation::__base::__dispatcher<>::__dispatch<>()
0x55f0340016f0: xls::dslx::BytecodeEmitter::HandleNameRef()
0x55f033fffc4d: xls::dslx::BytecodeEmitter::HandleInvocation()
0x55f033ff2a08: xls::dslx::BytecodeEmitter::HandleBinop()
0x55f033ff0a4e: xls::dslx::BytecodeEmitter::EmitExpression()
0x55f033fddbff: xls::dslx::ConstexprEvaluator::InterpretExpr()
0x55f033fdfa36: xls::dslx::ConstexprEvaluator::HandleBinop()
0x55f033fdd027: xls::dslx::ConstexprEvaluator::Evaluate()
0x55f033f785a7: xls::dslx::(anonymous namespace)::DeduceVisitor::HandleConstAssert()
```
**To Reproduce**
```
fn foo(x: u32) -> u32[8] { u32[8]:[x, ...] }
fn bar() {
for (i, _) in u32:0..u32:100 {
let result = foo(i);
const EXPECTED_SIZE = u32:2 * u32:4;
const RESULT_SIZE = array_size(result);
const_assert!(RESULT_SIZE == EXPECTED_SIZE);
const_assert!(array_size(result) == EXPECTED_SIZE);
}(());
}
```
The first `const_assert` works without any errors, so it appears that `array_size` can be used in a constexpr context correctly. The second `const_assert` generates the error above, saying that it can't find `result`.
**Expected behavior**
I would expect both to work the same, without the need to explicitly add a constant for the result size.
**Additional context**
It seems that this is only a problem inside a for loop. `unroll_for!` also does not cause an error (which makes sense I guess).
```
fn foo(x: u32) -> u32[8] { u32[8]:[x, ...] }
fn bar() {
let result = foo(u32:1);
const EXPECTED_SIZE = u32:2 * u32:4;
const RESULT_SIZE = array_size(result);
const_assert!(RESULT_SIZE == EXPECTED_SIZE);
const_assert!(array_size(result) == EXPECTED_SIZE);
}
```
Both `const_assert!`s pass without errors once the for loop is removed.
Contributor guide
Assessment
This issue has not been assessed yet.