From b69afe0506488d325ce4b2f6f4da91f7aa7f18cb Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Wed, 15 Mar 2023 09:39:23 -0700 Subject: [PATCH] More precise error for canonical reassignment in a value block These examples previously errored all the way in codegen, when we detected that a value block (eg a `while` test expression) was declaring a new variable. We now detect this in LeaveSSA and error. The actual fix is a bit tricky, we'd need to add a new declaration in the nearest block scope (or selectively not DCE the declaration if its reassigned in just this way). --- compiler/forget/src/SSA/LeaveSSA.ts | 12 ++++++++++++ .../error.while-with-assignment-in-test.expect.md | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/compiler/forget/src/SSA/LeaveSSA.ts b/compiler/forget/src/SSA/LeaveSSA.ts index 350b0ad141..3dde47ec6e 100644 --- a/compiler/forget/src/SSA/LeaveSSA.ts +++ b/compiler/forget/src/SSA/LeaveSSA.ts @@ -137,6 +137,12 @@ export function leaveSSA(fn: HIRFunction): void { originalLVal === undefined || originalLVal.lvalue === value.lvalue // in case this was pre-declared for the `for` initializer ) { + if (originalLVal === undefined && block.kind !== "block") { + CompilerError.invariant( + `TODO: Handle reassignment in a value block where the original declaration was removed by dead code elimination (DCE)`, + value.lvalue.place.loc + ); + } declarations.set(value.lvalue.place.identifier.name, { lvalue: value.lvalue, place: value.lvalue.place, @@ -170,6 +176,12 @@ export function leaveSSA(fn: HIRFunction): void { originalLVal === undefined || originalLVal.lvalue === value.lvalue ) { + if (originalLVal === undefined && block.kind !== "block") { + CompilerError.invariant( + `TODO: Handle reassignment in a value block where the original declaration was removed by dead code elimination (DCE)`, + place.loc + ); + } declarations.set(place.identifier.name, { lvalue: value.lvalue, place, diff --git a/compiler/forget/src/__tests__/fixtures/compiler/error.while-with-assignment-in-test.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/error.while-with-assignment-in-test.expect.md index 660f28ae3f..f3812861f6 100644 --- a/compiler/forget/src/__tests__/fixtures/compiler/error.while-with-assignment-in-test.expect.md +++ b/compiler/forget/src/__tests__/fixtures/compiler/error.while-with-assignment-in-test.expect.md @@ -19,7 +19,7 @@ function f(reader) { ## Error ``` -[ReactForget] Todo: (CodegenReactiveFunction::codegenInstructionValue) Cannot declare variables in a value block, tried to declare 'value' +[ReactForget] Invariant: TODO: Handle reassignment in a value block where the original declaration was removed by dead code elimination (DCE) (6:6) ``` \ No newline at end of file