Skip to content

Measurement of indexed qubit is typed incompatibly with scalar bit assignment #286

Description

@jianjian01

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions