In oq3_semantics 0.7.0, measure q[0] where q is declared as qubit[1] q is not deduced as bit, causing bit c; c = measure q[0]; to report a semantic IncompatibleTypesError. The equivalent scalar qubit case (qubit q; measure q) succeeds.
Per OpenQASM 3 semantics, q[0] is a single qubit, so measure q[0] should produce a single bit, and assignment to bit c should be legal.
Steps to Reproduce
use oq3_semantics::syntax_to_semantics::parse_source_string;
fn main() {
// Case 1: scalar qubit — passes (no errors)
let source_scalar = r#"
qubit q;
bit c;
c = measure q;
"#;
let result = parse_source_string(source_scalar, None);
println!("scalar: syntax errors: {}, semantic errors: {}",
result.any_syntax_errors(), result.any_semantic_errors());
for e in result.semantic_errors() {
println!(" {e:?}");
}
// Case 2: indexed qubit — FAILS with IncompatibleTypesError
let source_indexed = r#"
qubit[1] q;
bit c;
c = measure q[0];
"#;
let result = parse_source_string(source_indexed, None);
println!("indexed: syntax errors: {}, semantic errors: {}",
result.any_syntax_errors(), result.any_semantic_errors());
for e in result.semantic_errors() {
println!(" {e:?}");
}
}
Output
scalar: syntax errors: false, semantic errors: false
indexed: syntax errors: false, semantic errors: true
SemanticError { error_kind: IncompatibleTypesError, node: ... }
Root Cause
In syntax_to_semantics.rs, function gate_operand_to_asg_texpr, the IndexedIdentifier branch:
synast::GateOperand::IndexedIdentifier(ref indexed_identifier) => {
let (indexed_identifier, typ) =
indexed_identifier_to_asg_type(indexed_identifier, context);
if !matches!(typ, Type::QubitArray(_)) {
context.insert_error(IncompatibleTypesError, &gate_operand);
}
asg::GateOperand::IndexedIdentifier(indexed_identifier).to_texpr(typ)
// typ = QubitArray(D1(1)) ← should be Qubit for single-element access
}
indexed_identifier_to_asg_type returns the declared type of q — QubitArray(D1(1)) — instead of the element type after indexing. This array type flows into MeasureExpression::to_texpr in asg.rs:
Type::QubitArray(dims) => Type::BitArray(dims.clone(), IsConst::False),
// produces BitArray(D1(1)) instead of Bit
The assigned target c is Bit, so the mismatch triggers IncompatibleTypesError.
Related
- qubit q; bit[2] c; c[0] = measure q; — the reverse case works (indexed LHS, scalar measurement)
- Existing test test_from_string_measure_indexed only tests measure q[1]; without assignment, so this path was previously untested
Version
oq3_semantics 0.7.0, current main branch
In oq3_semantics 0.7.0, measure q[0] where q is declared as qubit[1] q is not deduced as bit, causing bit c; c = measure q[0]; to report a semantic IncompatibleTypesError. The equivalent scalar qubit case (qubit q; measure q) succeeds.
Per OpenQASM 3 semantics, q[0] is a single qubit, so measure q[0] should produce a single bit, and assignment to bit c should be legal.
Steps to Reproduce
Output
Root Cause
In syntax_to_semantics.rs, function gate_operand_to_asg_texpr, the IndexedIdentifier branch:
indexed_identifier_to_asg_typereturns the declared type of q — QubitArray(D1(1)) — instead of the element type after indexing. This array type flows into MeasureExpression::to_texpr in asg.rs:The assigned target c is Bit, so the mismatch triggers IncompatibleTypesError.
Related
Version
oq3_semantics 0.7.0, current main branch