Handle scopes with reassignment (by expanding scopes to avoid it)

This commit is contained in:
Joe Savona
2024-02-23 14:41:27 -08:00
parent a815d481c0
commit d3589367b0
2 changed files with 23 additions and 1 deletions
@@ -9,6 +9,7 @@ import { Environment } from "../HIR";
import {
HIRFunction,
Identifier,
IdentifierId,
Instruction,
makeInstructionId,
makeScopeId,
@@ -190,6 +191,10 @@ export function findDisjointMutableValues(
fn: HIRFunction
): DisjointSet<Identifier> {
const scopeIdentifiers = new DisjointSet<Identifier>();
const declarations: Map<IdentifierId, Place> | null = fn.env.config
.enableForest
? new Map()
: null;
for (const [_, block] of fn.body.blocks) {
/*
* If a phi is mutated after creation, then we need to alias all of its operands such that they
@@ -218,7 +223,14 @@ export function findDisjointMutableValues(
if (range.end > range.start + 1 || mayAllocate(fn.env, instr)) {
operands.push(instr.lvalue!.identifier);
}
if (
if (instr.value.kind === "DeclareLocal") {
if (declarations !== null) {
declarations.set(
instr.value.lvalue.place.identifier.id,
instr.value.lvalue.place
);
}
} else if (
instr.value.kind === "StoreLocal" ||
instr.value.kind === "StoreContext"
) {
@@ -234,6 +246,14 @@ export function findDisjointMutableValues(
) {
operands.push(instr.value.value.identifier);
}
if (declarations !== null) {
const declaration = declarations.get(
instr.value.lvalue.place.identifier.id
);
if (declaration !== undefined) {
operands.push(declaration.identifier);
}
}
} else if (instr.value.kind === "Destructure") {
for (const place of eachPatternOperand(instr.value.lvalue.pattern)) {
if (
@@ -440,6 +440,8 @@ const skipFilter = new Set([
"forest/forest-hook.flow",
"forest/access-property-of-non-escaping-value",
"forest/forest-TasksApp.flow",
"forest/forest-overwritten-let-binding-type-annotation.flow",
"forest/forest-phi-type-unused-initializer.flow",
// TODO: we probably want to always skip these
"rules-of-hooks/rules-of-hooks-0592bd574811",