fix(compiler): Add outside context to closures [LNG-317] (#1038)

This commit is contained in:
Dima 2024-01-11 11:00:32 +03:00 committed by GitHub
parent d46ee0347f
commit 85f3ecdf39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 80 additions and 19 deletions

View File

@ -1,23 +1,40 @@
aqua M
export bugLng314
export bugLng317
service MyOp("op"):
identity(s: string) -> string
ability WorkerJob:
runOnSingleWorker(w: string) -> string
runOnSingleWorker(w: string) -> []string
func disjoint_run{WorkerJob}() -> -> string:
run = func () -> string:
r <- WorkerJob.runOnSingleWorker()
func runJob(j: -> []string) -> []string:
<- j()
func disjoint_run{WorkerJob}() -> -> []string:
run = func () -> []string:
r <- WorkerJob.runOnSingleWorker("a")
<- r
<- run
func runJob(j: -> string) -> string:
<- j()
func empty() -> string:
a = "empty"
<- a
func bugLng314() -> string:
job2 = () -> string:
<- "strstrstr"
worker_job = WorkerJob(runOnSingleWorker = job2)
subnet_job <- disjoint_run{worker_job}()
res <- runJob(subnet_job)
func bugLng317() -> []string:
res: *string
outer = () -> string:
<- empty()
clos = () -> -> []string:
job2 = () -> []string:
res <- outer()
res <- MyOp.identity("identity")
<- res
<- job2
worker_job = WorkerJob(runOnSingleWorker = clos())
subnet_job <- disjoint_run{worker_job}()
finalRes <- runJob(subnet_job)
<- finalRes

View File

@ -2,7 +2,7 @@ module Closure declares *
import "@fluencelabs/aqua-lib/builtin.aqua"
export LocalSrv, closureIn, closureOut, closureBig, closureOut2, lng58Bug, multipleClosuresBugLNG262
export LocalSrv, closureIn, closureOut, closureBig, closureOut2, lng58Bug, multipleClosuresBugLNG262, lng317Bug
service MyOp("op"):
identity(s: string) -> string
@ -81,3 +81,37 @@ func multipleClosuresBugLNG262() -> i8, i8:
arr1 <- create(1)
arr2 <- create(2)
<- arr1(), arr2()
ability WorkerJob:
runOnSingleWorker(w: string) -> []string
func runJob(j: -> []string) -> []string:
<- j()
func disjoint_run{WorkerJob}() -> -> []string:
run = func () -> []string:
r <- WorkerJob.runOnSingleWorker("a")
<- r
<- run
func empty() -> string:
a = "empty"
<- a
func lng317Bug() -> []string:
res: *string
outer = () -> string:
<- empty()
clos = () -> -> []string:
job2 = () -> []string:
res <- outer()
res <- MyOp.identity("identity")
<- res
<- job2
worker_job = WorkerJob(runOnSingleWorker = clos())
subnet_job <- disjoint_run{worker_job}()
finalRes <- runJob(subnet_job)
<- finalRes

View File

@ -123,6 +123,7 @@ import { lng193BugCall } from "../examples/closureReturnRename.js";
import {
closuresCall,
multipleClosuresLNG262BugCall,
lng317BugCall
} from "../examples/closures.js";
import { closureArrowCaptureCall } from "../examples/closureArrowCapture.js";
import {
@ -1112,6 +1113,11 @@ describe("Testing examples", () => {
expect(result).toEqual([1, 2]);
});
it("closures.aqua bug LNG-317", async () => {
let result = await lng317BugCall();
expect(result).toEqual(["empty", "identity"]);
});
it("closureArrowCapture.aqua", async () => {
let result = await closureArrowCaptureCall("input");
expect(result).toEqual("call: ".repeat(4) + "input");

View File

@ -5,6 +5,7 @@ import {
registerLocalSrv,
closureOut2,
lng58Bug,
lng317Bug,
multipleClosuresBugLNG262
} from "../compiled/examples/closures.js";
import { config } from "../config.js";
@ -37,3 +38,7 @@ export async function lng58CBugCall(): Promise<string> {
export async function multipleClosuresLNG262BugCall(): Promise<[number, number]> {
return multipleClosuresBugLNG262();
}
export async function lng317BugCall(): Promise<string[]> {
return lng317Bug();
}

View File

@ -348,7 +348,7 @@ object ArrowInliner extends Logging {
// Rename arrows according to values
arrowsRenamed = Renamed(
valuesRenamed.renames.filterKeys(abilitiesArrows.keySet).toMap,
valuesRenamed.renames.view.filterKeys(abilitiesArrows.keySet).toMap,
abilitiesArrows.renamed(valuesRenamed.renames)
)

View File

@ -11,7 +11,7 @@ case class FuncRaw(
override def rawPartType: Type = arrow.`type`
def capturedVars: Set[String] = {
lazy val capturedVars: Set[String] = {
val freeBodyVars = arrow.body.usesVarNames.value
val argsNames = arrow.`type`.domain
.toLabelledList()

View File

@ -299,8 +299,7 @@ case class ClosureTag(
override def exportsVarNames: Set[String] = Set(func.name)
// FIXME: Is it correct?
override def usesVarNames: Set[String] = Set.empty
override def usesVarNames: Set[String] = func.capturedVars
override def renameExports(map: Map[String, String]): RawTag =
copy(func =