diff --git a/compiler/forget/src/HIR/HIR.ts b/compiler/forget/src/HIR/HIR.ts index dac8836537..9bd833ae59 100644 --- a/compiler/forget/src/HIR/HIR.ts +++ b/compiler/forget/src/HIR/HIR.ts @@ -546,6 +546,8 @@ export enum Effect { Freeze = "freeze", // This reference reads the value Read = "read", + // This reference reads and stores the value + Capture = "capture", // This reference may write to (mutate) the value Mutate = "mutate", // This reference may alias to (mutate) the value diff --git a/compiler/forget/src/Inference/InferAliasForStores.ts b/compiler/forget/src/Inference/InferAliasForStores.ts index 9572da76a0..63155a8207 100644 --- a/compiler/forget/src/Inference/InferAliasForStores.ts +++ b/compiler/forget/src/Inference/InferAliasForStores.ts @@ -30,7 +30,12 @@ export function inferAliasForStores( case "ComputedStore": case "PropertyStore": { for (const operand of eachInstructionValueOperand(value)) { - maybeAlias(aliases, lvalue.place, operand, instr.id); + if ( + operand.effect === Effect.Capture || + operand.effect === Effect.Store + ) { + maybeAlias(aliases, lvalue.place, operand, instr.id); + } } break; } diff --git a/compiler/forget/src/Inference/InferMutableLifetimes.ts b/compiler/forget/src/Inference/InferMutableLifetimes.ts index 145c2ee8e3..bc07edf69c 100644 --- a/compiler/forget/src/Inference/InferMutableLifetimes.ts +++ b/compiler/forget/src/Inference/InferMutableLifetimes.ts @@ -77,6 +77,7 @@ function inferPlace( )}!` ); } + case Effect.Capture: case Effect.Read: case Effect.Freeze: return; diff --git a/compiler/forget/src/Inference/InferReferenceEffects.ts b/compiler/forget/src/Inference/InferReferenceEffects.ts index 5f28a04d1b..bda7a26fd4 100644 --- a/compiler/forget/src/Inference/InferReferenceEffects.ts +++ b/compiler/forget/src/Inference/InferReferenceEffects.ts @@ -303,6 +303,10 @@ class Environment { effect = Effect.Store; break; } + case Effect.Capture: { + effect = Effect.Capture; + break; + } case Effect.Read: { effect = Effect.Read; break; @@ -542,7 +546,7 @@ function inferBlock(env: Environment, block: BasicBlock) { } case "ArrayExpression": { valueKind = ValueKind.Mutable; - effectKind = Effect.Read; + effectKind = Effect.Capture; lvalueEffect = Effect.Store; break; } @@ -564,7 +568,7 @@ function inferBlock(env: Environment, block: BasicBlock) { case "ObjectExpression": { valueKind = ValueKind.Mutable; // Object construction captures but does not modify the key/property values - effectKind = Effect.Read; + effectKind = Effect.Capture; lvalueEffect = Effect.Store; break; } @@ -658,7 +662,7 @@ function inferBlock(env: Environment, block: BasicBlock) { const effect = isObjectType(instrValue.object.identifier) ? Effect.Store : Effect.Mutate; - env.reference(instrValue.value, Effect.Read); + env.reference(instrValue.value, Effect.Capture); env.reference(instrValue.object, effect); const lvalue = instr.lvalue; @@ -688,8 +692,8 @@ function inferBlock(env: Environment, block: BasicBlock) { const effect = isObjectType(instrValue.object.identifier) ? Effect.Store : Effect.Mutate; - env.reference(instrValue.value, Effect.Read); - env.reference(instrValue.property, Effect.Read); + env.reference(instrValue.value, Effect.Capture); + env.reference(instrValue.property, Effect.Capture); env.reference(instrValue.object, effect); const lvalue = instr.lvalue;