Description
has_measurements(), remove_measurements(), has_barriers() and remove_barriers() fall back to self._statements when the module has not been unrolled. That list can still contain for / while / switch bodies, and the statement walker does not descend into them — so an occurrence inside a loop or switch is invisible.
Reproduction
from pyqasm import loads
src = """OPENQASM 3.0;
include "stdgates.inc";
qubit[2] q;
bit[2] c;
for int i in [0:1] { c[i] = measure q[i]; barrier q; }
"""
m = loads(src)
print(m.has_measurements(), m.has_barriers()) # False False <- wrong
m.remove_measurements() # no-op
m2 = loads(src)
m2.unroll()
print(m2.has_measurements(), m2.has_barriers()) # True True
Scope
Pre-existing — main behaves identically, and #345 strictly improves matters by closing the same gap for box and if on the unrolled path. Filed because #345's walker is the natural home for the remainder, and it would be easy to read that PR as having closed the class of bug entirely.
Note this only affects the non-unrolled path. for, while and switch are fully unrolled by unroll() and do not reach _unrolled_ast with their bodies intact, so Box and BranchingStatement really are the only two containers the unrolled walk has to handle.
Suggested fix
Either extend iter_quantum_statements to descend into loop and switch bodies for the non-unrolled path, or document on those four methods that they are only meaningful after unroll().
Found in review of #345 (L3).
Description
has_measurements(),remove_measurements(),has_barriers()andremove_barriers()fall back toself._statementswhen the module has not been unrolled. That list can still containfor/while/switchbodies, and the statement walker does not descend into them — so an occurrence inside a loop or switch is invisible.Reproduction
Scope
Pre-existing —
mainbehaves identically, and #345 strictly improves matters by closing the same gap forboxandifon the unrolled path. Filed because #345's walker is the natural home for the remainder, and it would be easy to read that PR as having closed the class of bug entirely.Note this only affects the non-unrolled path.
for,whileandswitchare fully unrolled byunroll()and do not reach_unrolled_astwith their bodies intact, soBoxandBranchingStatementreally are the only two containers the unrolled walk has to handle.Suggested fix
Either extend
iter_quantum_statementsto descend into loop and switch bodies for the non-unrolled path, or document on those four methods that they are only meaningful afterunroll().Found in review of #345 (L3).