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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions