fix deprecated assign update expression for nested expressions#3482
fix deprecated assign update expression for nested expressions#3482HABER7789 wants to merge 2 commits into
Conversation
@microsoft-github-policy-service agree company="Microsoft" |
|
|
||
| let mut value = value; | ||
| loop { |
There was a problem hiding this comment.
I realized that we only want to do the flattening if the index expression is "pure", in the sense that it always evaluates to the same value. So, you might want to wrap the loop in something like:
if is_pure_expr(value) {
loop {
...
}
}Here is an example Q# program in which we shouldn't suggest the Quick Fix, since quick-fixed program has different semantics than the original program.
operation NextIndex() : Int {
use q = Qubit();
H(q);
if MResetZ(q) == One { 1 } else { 0 }
}
@EntryPoint()
operation Main() : Int[][] {
mutable a = [[1, 2], [3, 4]];
// Deprecated form:
a w/= NextIndex() <- (a[NextIndex()] w/ 1 <- 7);
// After applying the Quick-Fix, the above expr will become:
// a[NextIndex(q)][1] = 7
a
}Only flatten nested `w/=` updates when the indices relied on being equal are pure, so the rewrite can't change how many times a side-effecting index runs. Impure indices fall back to the single-level rewrite; the assigned value is never required to be pure.
Fix deprecated assign-update quick fix for nested expressions
The
DeprecatedAssignUpdateExprquick fix flattens nestedw/=updates by matching index source text. That's unsafe for impure indices: the flattened form evaluates the index fewer times than the original, changing behavior.Now it only merges levels where the shared indices are pure, otherwise falling back to the safe single-level rewrite. The assigned value is never required to be pure (it's evaluated once either way).
Example (
NextIndex()returns a different value each call):Pure cases still flatten fully, e.g.
a w/= 0 <- (a[0] w/ 1 <- 7)→a[0][1] = 7.