[hir] Treat reassignment as mutation for context refs
The mutable range difference for assignment is just 1 which is something we usually don't track as we care about mutation and not assignment. But this isn't true for context refs whose (re) assignment is actually a mutation.
Sathya Gunasekaran committed
Mar 3, 2023 at 13:35 UTC
f002682322a4b332887ec8ab375a4921722c835c
1 file changed
+9
-3
compiler/forget/src/Inference/AnalyseFunctions.ts
+9
-3
@@ -88,7 +88,7 @@ function lower(func: HIRFunction) {
88
function infer(value: FunctionExpression, state: State, context: Place[]) {
89
const mutations = new Set(
90
value.loweredFunc.context
91
- .filter((dep) => isMutated(dep.identifier))
91
+ .filter((dep) => isMutatedOrReassigned(dep.identifier))
92
.map((m) => m.identifier.name)
93
.filter((m) => m !== null) as string[]
94
);
@@ -127,6 +127,12 @@ function infer(value: FunctionExpression, state: State, context: Place[]) {
127
}
128
}
129
130
-function isMutated(id: Identifier) {
131
- return id.mutableRange.end - id.mutableRange.start > 1;
130
+function isMutatedOrReassigned(id: Identifier) {
131
+ // This check checks for mutation and reassingnment, so the usual check for
132
+ // mutation (ie, `mutableRange.end - mutableRange.start > 1`) isn't quite
133
+ // enough.
134
+ //
135
+ // We need to track re-assignments in context refs as we need to reflect the
136
+ // re-assignment back to the captured refs.
137
+ return id.mutableRange.end > id.mutableRange.start;
138
}