diff --git a/compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts b/compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts index fd8e0ad5fb..9c36db0702 100644 --- a/compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts +++ b/compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts @@ -12,10 +12,10 @@ import { InstructionKind, InstructionValue, makeInstructionId, - MutableRange, Place, ReactiveBlock, ReactiveFunction, + ReactiveScope, ReactiveValueBlock, } from "../HIR/HIR"; import { eachInstructionValueOperand } from "../HIR/visitors"; @@ -39,7 +39,7 @@ export function propagateScopeDependencies(fn: ReactiveFunction): void { id: makeInstructionId(0), }); } - visit(fn.body, dependencies, declarations, null); + visit(fn.body, dependencies, declarations, []); } enum DeclKind { @@ -49,11 +49,13 @@ enum DeclKind { type DeclMap = Map; +type Scopes = Array; + function visit( block: ReactiveBlock, dependencies: Set, declarations: DeclMap, - scopeRange: MutableRange | null + scopes: Scopes ): void { for (const item of block) { switch (item.kind) { @@ -61,19 +63,16 @@ function visit( const scopeDependencies: Set = new Set(); // TODO: it would be sufficient to use a single mapping of declarations const scopeDeclarations: DeclMap = new Map(declarations); - visit( - item.instructions, - scopeDependencies, - scopeDeclarations, - item.scope.range - ); + scopes.push(item.scope); + visit(item.instructions, scopeDependencies, scopeDeclarations, scopes); + scopes.pop(); item.scope.dependencies = scopeDependencies; for (const dep of scopeDependencies) { // propagate dependencies upward using the same rules as // normal dependency collection. child scopes may have dependencies // on values created within the outer scope, which necessarily cannot // be dependencies of the outer scope - visitOperand(dep, dependencies, declarations, scopeRange); + visitOperand(dep, dependencies, declarations, scopes); } for (const [ident, kind] of scopeDeclarations) { declarations.set(ident, kind); @@ -81,12 +80,7 @@ function visit( break; } case "instruction": { - visitInstruction( - item.instruction, - dependencies, - declarations, - scopeRange - ); + visitInstruction(item.instruction, dependencies, declarations, scopes); break; } case "terminal": { @@ -98,69 +92,44 @@ function visit( } case "return": { if (terminal.value !== null) { - visitOperand( - terminal.value, - dependencies, - declarations, - scopeRange - ); + visitOperand(terminal.value, dependencies, declarations, scopes); } break; } case "throw": { - visitOperand( - terminal.value, - dependencies, - declarations, - scopeRange - ); + visitOperand(terminal.value, dependencies, declarations, scopes); break; } case "for": { - visitValueBlock( - terminal.init, - dependencies, - declarations, - scopeRange - ); - visitValueBlock( - terminal.test, - dependencies, - declarations, - scopeRange - ); + visitValueBlock(terminal.init, dependencies, declarations, scopes); + visitValueBlock(terminal.test, dependencies, declarations, scopes); visitValueBlock( terminal.update, dependencies, declarations, - scopeRange + scopes ); - visit(terminal.loop, dependencies, declarations, scopeRange); + visit(terminal.loop, dependencies, declarations, scopes); break; } case "while": { - visitValueBlock( - terminal.test, - dependencies, - declarations, - scopeRange - ); - visit(terminal.loop, dependencies, declarations, scopeRange); + visitValueBlock(terminal.test, dependencies, declarations, scopes); + visit(terminal.loop, dependencies, declarations, scopes); break; } case "if": { - visitOperand(terminal.test, dependencies, declarations, scopeRange); - visit(terminal.consequent, dependencies, declarations, scopeRange); + visitOperand(terminal.test, dependencies, declarations, scopes); + visit(terminal.consequent, dependencies, declarations, scopes); if (terminal.alternate !== null) { - visit(terminal.alternate, dependencies, declarations, scopeRange); + visit(terminal.alternate, dependencies, declarations, scopes); } break; } case "switch": { - visitOperand(terminal.test, dependencies, declarations, scopeRange); + visitOperand(terminal.test, dependencies, declarations, scopes); for (const case_ of terminal.cases) { if (case_.block !== undefined) { - visit(case_.block, dependencies, declarations, scopeRange); + visit(case_.block, dependencies, declarations, scopes); } } break; @@ -185,7 +154,7 @@ function visitValueBlock( block: ReactiveValueBlock, dependencies: Set, declarations: DeclMap, - scopeRange: MutableRange | null + scopes: Scopes ): void { for (const initItem of block.instructions) { if (initItem.kind === "instruction") { @@ -193,12 +162,12 @@ function visitValueBlock( initItem.instruction, dependencies, declarations, - scopeRange + scopes ); } } if (block.value !== null) { - visitInstructionValue(block.value, dependencies, declarations, scopeRange); + visitInstructionValue(block.value, dependencies, declarations, scopes); } } @@ -206,7 +175,7 @@ function visitOperand( maybeDependency: Place, dependencies: Set, declarations: DeclMap, - scopeRange: MutableRange | null + scopes: Scopes ): void { const decl = declarations.get(maybeDependency.identifier); @@ -215,22 +184,19 @@ function visitOperand( // some later code needs access to the value. if (decl !== undefined) { const operandScope = maybeDependency.identifier.scope; - if ( - operandScope !== null && - ((scopeRange !== null && operandScope.range.end <= scopeRange.start) || - scopeRange === null) - ) { + if (operandScope !== null && scopes.indexOf(operandScope) === -1) { operandScope.outputs.add(maybeDependency.identifier); } } // If this operand is used in a scope, has a dynamic value, and was defined // before this scope, then its a dependency of the scope. + const currentScope = scopes.at(-1); if ( decl !== undefined && decl.kind !== DeclKind.Const && - scopeRange !== null && - decl.id < scopeRange.start + currentScope !== undefined && + decl.id < currentScope.range.start ) { // Check if there is an existing dependency that describes this operand for (const dep of dependencies) { @@ -272,7 +238,7 @@ function visitInstructionValue( value: InstructionValue, dependencies: Set, declarations: DeclMap, - scopeRange: MutableRange | null + scopes: Scopes ): void { for (const operand of eachInstructionValueOperand(value)) { // check for method invocation, we want to depend on the callee, not the method @@ -285,9 +251,9 @@ function visitInstructionValue( ...operand, memberPath: operand.memberPath.slice(0, -1), }; - visitOperand(callee, dependencies, declarations, scopeRange); + visitOperand(callee, dependencies, declarations, scopes); } else { - visitOperand(operand, dependencies, declarations, scopeRange); + visitOperand(operand, dependencies, declarations, scopes); } } } @@ -296,9 +262,9 @@ function visitInstruction( instr: Instruction, dependencies: Set, declarations: DeclMap, - scopeRange: MutableRange | null + scopes: Scopes ): void { - visitInstructionValue(instr.value, dependencies, declarations, scopeRange); + visitInstructionValue(instr.value, dependencies, declarations, scopes); const { lvalue } = instr; if ( lvalue !== null && diff --git a/compiler/forget/src/__tests__/fixtures/hir/_bug_independently-memoize-object-property.expect.md b/compiler/forget/src/__tests__/fixtures/hir/_bug_independently-memoize-object-property.expect.md index 37a41992a5..9bb7e57af5 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/_bug_independently-memoize-object-property.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/_bug_independently-memoize-object-property.expect.md @@ -27,8 +27,8 @@ bb0: [3] Const mutate y$12_@1:TObject[3:6] = Object { a: read a$8 } [4] Const mutate z$13_@2 = Array [read b$9, read c$10] [5] Reassign mutate y$12_@1.y[3:6] = read z$13_@2 - [6] Const mutate t12$14_@3 = Array [read x$11_@0:TObject, read y$12_@1:TObject] - [7] Return freeze t12$14_@3 + [6] Const mutate t13$14_@3 = Array [read x$11_@0:TObject, read y$12_@1:TObject] + [7] Return freeze t13$14_@3 ``` ## Reactive Scopes @@ -45,7 +45,7 @@ function foo( } scope @1 [3:6] deps=[read a$8, read b$9, read c$10] out=[y$12_@1] { [3] Const mutate y$12_@1:TObject[3:6] = Object { a: read a$8 } - scope @2 [4:5] deps=[read b$9, read c$10] out=[] { + scope @2 [4:5] deps=[read b$9, read c$10] out=[z$13_@2] { [4] Const mutate z$13_@2 = Array [read b$9, read c$10] } [5] Reassign mutate y$12_@1.y[3:6] = read z$13_@2 @@ -91,12 +91,15 @@ function foo$0(a$8, b$9, c$10) { }; const c_8 = $[8] !== b$9; const c_9 = $[9] !== c$10; + let z$13; if (c_8 || c_9) { - const z$13 = [b$9, c$10]; + z$13 = [b$9, c$10]; $[8] = b$9; $[9] = c$10; + $[10] = z$13; } else { + z$13 = $[10]; } y$12.y = z$13; @@ -108,20 +111,20 @@ function foo$0(a$8, b$9, c$10) { y$12 = $[7]; } - const c_10 = $[10] !== x$11; - const c_11 = $[11] !== y$12; - let t12$14; + const c_11 = $[11] !== x$11; + const c_12 = $[12] !== y$12; + let t13$14; - if (c_10 || c_11) { - t12$14 = [x$11, y$12]; - $[10] = x$11; - $[11] = y$12; - $[12] = t12$14; + if (c_11 || c_12) { + t13$14 = [x$11, y$12]; + $[11] = x$11; + $[12] = y$12; + $[13] = t13$14; } else { - t12$14 = $[12]; + t13$14 = $[13]; } - return t12$14; + return t13$14; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/component.expect.md b/compiler/forget/src/__tests__/fixtures/hir/component.expect.md index 510abef4a4..474b21088a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/component.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/component.expect.md @@ -95,11 +95,11 @@ bb2: [35] Const mutate $68 = "\n " [36] Const mutate $69:TPrimitive = "h1" [37] Const mutate $70 = " Items" - [38] Const mutate t6$71_@4 = JSX {freeze count$66:TProp}{read $70} + [38] Const mutate t7$71_@4 = JSX {freeze count$66:TProp}{read $70} [39] Const mutate $72 = "\n " [40] Const mutate $73 = "\n " - [41] Const mutate t9$74_@5 = JSX {read $68}{read t6$71_@4}{read $72}{freeze renderedItems$32_@0:TFunction}{read $73} - [42] Return read t9$74_@5 + [41] Const mutate t10$74_@5 = JSX {read $68}{read t7$71_@4}{read $72}{freeze renderedItems$32_@0:TFunction}{read $73} + [42] Return read t10$74_@5 ``` ## Reactive Scopes @@ -114,7 +114,7 @@ function Component( [3] Const mutate renderedItems$32_@0:TFunction[3:33] = Array [] [4] Const mutate seen$33_@0:TFunction[3:33] = New mutate Set$6() [5] Const mutate $34:TPrimitive = 0 - scope @2 [6:7] deps=[read maxItems$31:TProp] out=[] { + scope @2 [6:7] deps=[read maxItems$31:TProp] out=[max$35_@2] { [6] Const mutate max$35_@2:TPrimitive = Call mutate Math$8.max(read $34:TPrimitive, read maxItems$31:TProp) } for ( @@ -182,11 +182,14 @@ function Component$0(props$29) { renderedItems$32 = []; const seen$33 = new Set$6(); const c_4 = $[4] !== maxItems$31; + let max$35; if (c_4) { - const max$35 = Math$8.max(0, maxItems$31); + max$35 = Math$8.max(0, maxItems$31); $[4] = maxItems$31; + $[5] = max$35; } else { + max$35 = $[5]; } for (let i$36 = 0; i$36 < items$30.length; i$36 = i$36 + 1, i$36) { @@ -217,36 +220,36 @@ function Component$0(props$29) { } const count$66 = renderedItems$32.length; - const c_5 = $[5] !== count$66; - let t6$71; + const c_6 = $[6] !== count$66; + let t7$71; - if (c_5) { - t6$71 =

{count$66} Items

; - $[5] = count$66; - $[6] = t6$71; + if (c_6) { + t7$71 =

{count$66} Items

; + $[6] = count$66; + $[7] = t7$71; } else { - t6$71 = $[6]; + t7$71 = $[7]; } - const c_7 = $[7] !== t6$71; - const c_8 = $[8] !== renderedItems$32; - let t9$74; + const c_8 = $[8] !== t7$71; + const c_9 = $[9] !== renderedItems$32; + let t10$74; - if (c_7 || c_8) { - t9$74 = ( + if (c_8 || c_9) { + t10$74 = (
- {t6$71} + {t7$71} {renderedItems$32}
); - $[7] = t6$71; - $[8] = renderedItems$32; - $[9] = t9$74; + $[8] = t7$71; + $[9] = renderedItems$32; + $[10] = t10$74; } else { - t9$74 = $[9]; + t10$74 = $[10]; } - return t9$74; + return t10$74; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-with-aliasing.expect.md b/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-with-aliasing.expect.md index d532cb7e35..11c5cb77f5 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-with-aliasing.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-with-aliasing.expect.md @@ -102,7 +102,7 @@ function Component( } scope @1 [2:15] deps=[read a$11_@0:TObject] out=[] { [2] Const mutate b$12_@1[2:15] = Array [read a$11_@0:TObject] - scope @2 [3:4] deps=[] out=[] { + scope @2 [3:4] deps=[] out=[c$13_@2] { [3] Const mutate c$13_@2:TObject = Object { } } [4] Const mutate d$14_@1:TObject[2:15] = Object { c: read c$13_@2:TObject } @@ -144,10 +144,13 @@ function Component$0(props$10) { if (c_1) { const b$12 = [a$11]; + let c$13; if (true) { - const c$13 = {}; + c$13 = {}; + $[2] = c$13; } else { + c$13 = $[2]; } const d$14 = { diff --git a/compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md b/compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md index cab058c48e..faf7606a5b 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md @@ -129,7 +129,7 @@ function Component( scope @0 [1:18] deps=[] out=[] { [1] Const mutate a$12_@0:TObject[1:18] = Object { } [2] Const mutate b$13_@0:TObject[1:18] = Object { } - scope @1 [3:4] deps=[] out=[] { + scope @1 [3:4] deps=[] out=[c$14_@1] { [3] Const mutate c$14_@1:TObject = Object { } } [4] Const mutate d$15_@0:TObject[1:18] = Object { } @@ -163,12 +163,17 @@ function Component( ```javascript function Component$0(props$11) { + const $ = React.useMemoCache(); if (true) { const a$12 = {}; const b$13 = {}; + let c$14; + if (true) { - const c$14 = {}; + c$14 = {}; + $[0] = c$14; } else { + c$14 = $[0]; } const d$15 = {}; diff --git a/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowing-within-block.expect.md b/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowing-within-block.expect.md index 1c2a121eea..d55cd424a0 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowing-within-block.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowing-within-block.expect.md @@ -34,8 +34,8 @@ bb4: bb3: predecessor blocks: bb4 bb2 [7] Const mutate $13:TPrimitive = "div" - [8] Const mutate $15_@2 = JSX {freeze y$12_@1:TFunction} - [9] Call mutate x$11_@0.push(read $15_@2) + [8] Const mutate t8$15_@2 = JSX {freeze y$12_@1:TFunction} + [9] Call mutate x$11_@0.push(read t8$15_@2) [10] Goto bb1 bb1: predecessor blocks: bb3 bb0 @@ -60,7 +60,7 @@ function foo( } } [7] Const mutate $13:TPrimitive = "div" - scope @2 [8:9] deps=[freeze y$12_@1:TFunction] out=[] { + scope @2 [8:9] deps=[freeze y$12_@1:TFunction] out=[$15_@2] { [8] Const mutate $15_@2 = JSX {freeze y$12_@1:TFunction} } [9] Call mutate x$11_@0.push(read $15_@2) @@ -103,13 +103,17 @@ function foo$0(a$8, b$9, c$10) { } const c_7 = $[7] !== y$12; + let t8$15; if (c_7) { + t8$15 =
{y$12}
; $[7] = y$12; + $[8] = t8$15; } else { + t8$15 = $[8]; } - x$11.push(
{y$12}
); + x$11.push(t8$15); } $[0] = a$8; diff --git a/compiler/forget/src/__tests__/fixtures/hir/reactive-scope-grouping.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reactive-scope-grouping.expect.md index f470a53c60..6e068a6436 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reactive-scope-grouping.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reactive-scope-grouping.expect.md @@ -33,7 +33,7 @@ function foo( ) { scope @0 [1:6] deps=[] out=[x$4_@0] { [1] Const mutate x$4_@0:TObject[1:6] = Object { } - scope @1 [2:5] deps=[] out=[] { + scope @1 [2:5] deps=[] out=[y$5_@1] { [2] Const mutate y$5_@1:TFunction[2:5] = Array [] [3] Const mutate z$6_@1:TObject[2:5] = Object { } [4] Call mutate y$5_@1.push(mutate z$6_@1:TObject) @@ -53,12 +53,15 @@ function foo$0() { let x$4; if (true) { x$4 = {}; + let y$5; if (true) { - const y$5 = []; + y$5 = []; const z$6 = {}; y$5.push(z$6); + $[1] = y$5; } else { + y$5 = $[1]; } x$4.y = y$5; diff --git a/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes-if.expect.md index 0933bb486b..f8877a4aae 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes-if.expect.md @@ -27,8 +27,8 @@ bb2: [3] Const mutate y$12_@1:TFunction[3:5] = Array [] [4] Call mutate y$12_@1.push(read b$9) [5] Const mutate $13:TPrimitive = "div" - [6] Const mutate $14_@2 = JSX {freeze y$12_@1:TFunction} - [7] Call mutate x$11_@0.push(read $14_@2) + [6] Const mutate t7$14_@2 = JSX {freeze y$12_@1:TFunction} + [7] Call mutate x$11_@0.push(read t7$14_@2) [8] Goto bb1 bb3: predecessor blocks: bb0 @@ -55,7 +55,7 @@ function foo( [4] Call mutate y$12_@1.push(read b$9) } [5] Const mutate $13:TPrimitive = "div" - scope @2 [6:7] deps=[freeze y$12_@1:TFunction] out=[] { + scope @2 [6:7] deps=[freeze y$12_@1:TFunction] out=[$14_@2] { [6] Const mutate $14_@2 = JSX {freeze y$12_@1:TFunction} } [7] Call mutate x$11_@0.push(read $14_@2) @@ -94,13 +94,17 @@ function foo$0(a$8, b$9, c$10) { } const c_6 = $[6] !== y$12; + let t7$14; if (c_6) { + t7$14 =
{y$12}
; $[6] = y$12; + $[7] = t7$14; } else { + t7$14 = $[7]; } - x$11.push(
{y$12}
); + x$11.push(t7$14); } else { x$11.push(c$10); } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md index b3897f97cc..bc29bd4296 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md @@ -48,8 +48,8 @@ bb0: [1] Const mutate a$11_@0[1:10] = Array [] [2] Const mutate b$12_@0:TObject[1:10] = Object { } [3] Call mutate foo$4:TFunction(mutate a$11_@0, mutate b$12_@0:TObject) - [4] Const mutate $13_@1 = Call mutate foo$4:TFunction() - [5] If (read $13_@1) then:bb2 else:bb1 fallthrough=bb1 + [4] Const mutate t2$13_@1 = Call mutate foo$4:TFunction() + [5] If (read t2$13_@1) then:bb2 else:bb1 fallthrough=bb1 bb2: predecessor blocks: bb0 [6] Const mutate $14:TPrimitive = "div" @@ -59,8 +59,8 @@ bb1: predecessor blocks: bb2 bb0 [9] Call mutate foo$4:TFunction(read a$11_@0, mutate b$12_@0:TObject) [10] Const mutate $19:TPrimitive = "div" - [11] Const mutate t5$20_@3 = JSX - [12] Return read t5$20_@3 + [11] Const mutate t6$20_@3 = JSX + [12] Return read t6$20_@3 ``` ## Reactive Scopes @@ -73,7 +73,7 @@ function Component( [1] Const mutate a$11_@0[1:10] = Array [] [2] Const mutate b$12_@0:TObject[1:10] = Object { } [3] Call mutate foo$4:TFunction(mutate a$11_@0, mutate b$12_@0:TObject) - scope @1 [4:5] deps=[] out=[] { + scope @1 [4:5] deps=[] out=[$13_@1] { [4] Const mutate $13_@1 = Call mutate foo$4:TFunction() } if (read $13_@1) { @@ -104,18 +104,22 @@ function Component$0(props$10) { a$11 = []; b$12 = {}; foo$4(a$11, b$12); + let t2$13; if (true) { + t2$13 = foo$4(); + $[2] = t2$13; } else { + t2$13 = $[2]; } - if (foo$4()) { - const c_2 = $[2] !== a$11; + if (t2$13) { + const c_3 = $[3] !== a$11; - if (c_2) { + if (c_3) { const _$15 =
; - $[2] = a$11; + $[3] = a$11; } else { } } @@ -128,20 +132,20 @@ function Component$0(props$10) { b$12 = $[1]; } - const c_3 = $[3] !== a$11; - const c_4 = $[4] !== b$12; - let t5$20; + const c_4 = $[4] !== a$11; + const c_5 = $[5] !== b$12; + let t6$20; - if (c_3 || c_4) { - t5$20 =
; - $[3] = a$11; - $[4] = b$12; - $[5] = t5$20; + if (c_4 || c_5) { + t6$20 =
; + $[4] = a$11; + $[5] = b$12; + $[6] = t6$20; } else { - t5$20 = $[5]; + t6$20 = $[6]; } - return t5$20; + return t6$20; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-if.expect.md index b5f90a53d2..fff573da00 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-if.expect.md @@ -46,12 +46,12 @@ function foo( scope @0 [1:9] deps=[read a$5] out=[x$6_@0] { [1] Const mutate x$6_@0:TObject[1:9] = Object { } if (read a$5) { - scope @1 [3:4] deps=[] out=[] { + scope @1 [3:4] deps=[] out=[y$7_@1] { [3] Const mutate y$7_@1:TObject = Object { } } [4] Reassign mutate x$6_@0.y[1:9] = read y$7_@1:TObject } else { - scope @2 [6:7] deps=[] out=[] { + scope @2 [6:7] deps=[] out=[z$8_@2] { [6] Const mutate z$8_@2:TObject = Object { } } [7] Reassign mutate x$6_@0.z[1:9] = read z$8_@2:TObject @@ -73,16 +73,24 @@ function foo$0(a$5) { x$6 = {}; if (a$5) { + let y$7; + if (true) { - const y$7 = {}; + y$7 = {}; + $[2] = y$7; } else { + y$7 = $[2]; } x$6.y = y$7; } else { + let z$8; + if (true) { - const z$8 = {}; + z$8 = {}; + $[3] = z$8; } else { + z$8 = $[3]; } x$6.z = z$8; diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-inside-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-inside-if.expect.md index 2e4f48973b..a12459b363 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-inside-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-inside-if.expect.md @@ -52,7 +52,7 @@ function foo( [4] Reassign mutate x$7_@0.y[1:10] = read y$8_@0:TObject [5] Call mutate mutate$4:TFunction(mutate y$8_@0:TObject) } else { - scope @1 [7:8] deps=[] out=[] { + scope @1 [7:8] deps=[] out=[z$9_@1] { [7] Const mutate z$9_@1:TObject = Object { } } [8] Reassign mutate x$7_@0.z[1:10] = read z$9_@1:TObject @@ -78,9 +78,13 @@ function foo$0(a$6) { x$7.y = y$8; mutate$4(y$8); } else { + let z$9; + if (true) { - const z$9 = {}; + z$9 = {}; + $[2] = z$9; } else { + z$9 = $[2]; } x$7.z = z$9; diff --git a/compiler/forget/src/__tests__/fixtures/hir/type-test-field-store.expect.md b/compiler/forget/src/__tests__/fixtures/hir/type-test-field-store.expect.md index 50ce73d71a..828dec3456 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/type-test-field-store.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/type-test-field-store.expect.md @@ -29,7 +29,7 @@ function component( ) { scope @0 [1:4] deps=[] out=[x$4_@0] { [1] Const mutate x$4_@0:TObject[1:4] = Object { } - scope @1 [2:3] deps=[] out=[] { + scope @1 [2:3] deps=[] out=[q$5_@1] { [2] Const mutate q$5_@1:TObject = Object { } } [3] Reassign mutate x$4_@0.t[1:4] = read q$5_@1:TObject @@ -48,10 +48,13 @@ function component$0() { let x$4; if (true) { x$4 = {}; + let q$5; if (true) { - const q$5 = {}; + q$5 = {}; + $[1] = q$5; } else { + q$5 = $[1]; } x$4.t = q$5;