Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[Panic] Assignment in the right operand of a measurement-dependent `and`/`or`

Open
#3,976 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
56/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
python, rust
Domain
compilers, testing

Research direction

Start with the Q# reproducer in the issue and compare simulator results with Adaptive_RI, Adaptive_RIF, and Adaptive QIR runs; the reported panic occurs during partial evaluation at qsc_eval/src/lib.rs:2380. Check the control case without a later use of the mutated variable and the related issues #3950 and #3802. Done means the affected profiles handle the conditional assignment without panicking or returning a wrong value.

Written by the indexing model from the issue text.

Description

bug needs triage
operation Main() : Int {
    use q = Qubit();
    mutable v = 4;
    let _ = (MResetZ(q) == One) and { set v = 0; false };
    v + 1
}
  • Failure: the simulator returns 5. Adaptive_RI, Adaptive_RIF, and Adaptive panic with value is not addable: Var
    (qsc_eval/src/lib.rs:2380, during partial evaluation). Later arithmetic or comparisons on v give the other
    messages: value doesn't support binop gte, value should support div, value should be number, value should be Int, got Var, and value should be Double, got Var.
  • Other builds: on f05438eb the program panics the same way. On ca2fe553 it compiles but returns 1, as if
    the skipped assignment ran.
  • Related:
    • #3950 (open) covers an array update inside a nested and.
    • #3802 (closed) had the wrong-value symptom for this shape.
"""An assignment in the right operand of a measurement-dependent `and`/`or`, followed by a use of that variable.

The right operand of `(MResetZ(q) == One) and { set v = 0; false }` runs only if the measurement is `One`. Here the
qubit is fresh, so it measures `Zero`, the assignment is skipped, and `v + 1` is 5. On upstream/main, Adaptive_RI,
Adaptive_RIF and Adaptive panic in partial evaluation; the message depends on how `v` is used next ("value is not
addable: Var", "value doesn't support binop gte", "value should support div", ...). Some other builds compile it
instead and return 1, as if the skipped assignment ran (the symptom of the closed #3802). Base rejects the program
(dynamic Bool). Related: #3950 (open) covers an array update inside a nested `and`.

Each compiled program is run with `qdk.simulation.run_qir` and compared with the simulator, so the script reports both
the panic and the wrong-value form.

Requires only the `qdk` package. Exits 0 while the bug (a panic or a wrong value) reproduces.
"""

import sys

from qdk import Context, TargetProfile
from qdk.simulation import run_qir

PROFILES = ("Adaptive_RI", "Adaptive_RIF", "Adaptive")

PROGRAMS = {
    "and, then +": """
operation Main() : Int {
    use q = Qubit();
    mutable v = 4;
    let _ = (MResetZ(q) == One) and { set v = 0; false };
    v + 1
}""",
    "or, then >=": """
operation Main() : Bool {
    use q = Qubit();
    mutable v = 4;
    let _ = (MResetZ(q) == Zero) or { set v = 0; true };
    v >= 3
}""",
    "and, then / (Double)": """
operation Main() : Double {
    use q = Qubit();
    mutable v = 4.0;
    let _ = (MResetZ(q) == One) and { set v = 0.0; false };
    v / 2.0
}""",
    "no use after the and (control)": """
operation Main() : Int {
    use q = Qubit();
    mutable v = 4;
    let _ = (MResetZ(q) == One) and { set v = 0; false };
    4
}""",
}

reproduced = False
for label, source in PROGRAMS.items():
    sim = Context()
    sim.eval(source)
    expected = sim.run("Main()", 1, seed=1)[0]
    print(f"{label}: simulator {expected}")
    for profile in PROFILES:
        ctx = Context(target_profile=getattr(TargetProfile, profile))
        try:
            ctx.eval(source)
            qir = ctx.compile("Main()")
        except BaseException as e:  # pyo3's PanicException derives from BaseException
            panic = type(e).__name__ == "PanicException"
            print(f"  {profile:13s} {'PANIC' if panic else 'error'}: {' '.join(str(e).split())[:100]}")
            reproduced |= panic and "(control)" not in label
            continue
        actual = run_qir(qir, shots=1, seed=1)[0]
        wrong = actual != expected
        print(f"  {profile:13s} QIR result {actual}{'  <-- WRONG' if wrong else ''}")
        reproduced |= wrong and "(control)" not in label

print("REPRODUCED" if reproduced else "NOT REPRODUCED")
sys.exit(0 if reproduced else 1)
Dominant language
Rust
Stars
1k
Forks
219
Avg merge
3d 8m
Merged PRs (30d)
71

Getting set up

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from microsoft/qdk

All issues in microsoft/qdk

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.