cue
cue copied to clipboard
stack overflow with a definition embedding structural cycle
exec cue export in.cue
-- in.cue --
@experiment(aliasv2)
#Def~(_,z): {
_,
_out: {
if (z & string) != _|_ {
str: true
},
}
}
out: #Def & "foo"
As of 2c9c7d1f23e582f2f7e053714582e057bc783700:
> exec cue export in.cue
[stderr]
runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0x886da68c540 stack=[0x886da68c000, 0x886fa68c000]
fatal error: stack overflow
runtime stack:
runtime.throw({0x1125b58?, 0x44f25a?})
/home/mvdan/tip/src/runtime/panic.go:1225 +0x48 fp=0x7f68337fdcf0 sp=0x7f68337fdcc0 pc=0x499d08
runtime.newstack()
/home/mvdan/tip/src/runtime/stack.go:1160 +0x5fd fp=0x7f68337fde20 sp=0x7f68337fdcf0 pc=0x47d75d
runtime.morestack()
/home/mvdan/tip/src/runtime/asm_amd64.s:636 +0x7d fp=0x7f68337fde28 sp=0x7f68337fde20 pc=0x49fd3d
goroutine 1 gp=0x886ba2101c0 m=3 mp=0x886ba2c7008 [running]:
cuelang.org/go/internal/core/adt.(*OpContext).evalStateCI(0x886ba572288, {0x12f9f40, 0x886ba566600}, {0x0, 0x41, 0x4, 0x0, 0x0})
/home/mvdan/src/c/cue/internal/core/adt/context.go:666 +0x112f fp=0x886da68c550 sp=0x886da68c548 pc=0x88874f
cuelang.org/go/internal/core/adt.(*OpContext).evalState(...)
/home/mvdan/src/c/cue/internal/core/adt/context.go:662
cuelang.org/go/internal/core/adt.(*OpContext).validate(0x886ba572288, 0x886d36017e0, {0x12fe3d8, 0x886ba4fbcc0}, {0x12f9f40, 0x886ba566600}, 0xb, {0x0, 0x8, 0x3, ...})
/home/mvdan/src/c/cue/internal/core/adt/expr.go:1332 +0x26e fp=0x886da68c718 sp=0x886da68c550 pc=0x8a3cce
cuelang.org/go/internal/core/adt.(*BinaryExpr).evaluate(0x886ba566630, 0x886ba572288, {0x0, 0x8, 0x3, 0x1, 0x0})
/home/mvdan/src/c/cue/internal/core/adt/expr.go:1278 +0x1cd fp=0x886da68c808 sp=0x886da68c718 pc=0x8a346d
cuelang.org/go/internal/core/adt.(*OpContext).evalStateCI(0x886ba572288, {0x12f9f40, 0x886ba566630}, {0x0, 0x8, 0x3, 0x1, 0x0})
/home/mvdan/src/c/cue/internal/core/adt/context.go:719 +0x59e fp=0x886da68ca80 sp=0x886da68c808 pc=0x887bbe
cuelang.org/go/internal/core/adt.(*OpContext).evalState(...)
/home/mvdan/src/c/cue/internal/core/adt/context.go:662
cuelang.org/go/internal/core/adt.(*OpContext).value(0x886ba572288, {0x12f9f40?, 0x886ba566630?}, {0x0, 0x8, 0x3, 0x1, 0x0})
/home/mvdan/src/c/cue/internal/core/adt/context.go:654 +0x77 fp=0x886da68cae8 sp=0x886da68ca80 pc=0x887597
cuelang.org/go/internal/core/adt.(*IfClause).yield(0x28?, 0x886c5b20360)
/home/mvdan/src/c/cue/internal/core/adt/expr.go:2189 +0x45 fp=0x886da68cb28 sp=0x886da68cae8 pc=0x8a9285
cuelang.org/go/internal/core/adt.(*OpContext).yield(0x886ba572288, 0x886d3665ae0, 0x886d36017e0, 0x886ba50c8a0, {0x0, 0x7fff, 0x1, 0x0, 0x0}, 0x886c5a4d4c0)
/home/mvdan/src/c/cue/internal/core/adt/comprehension.go:303 +0x2f0 fp=0x886da68cca8 sp=0x886da68cb28 pc=0x87c410
cuelang.org/go/internal/core/adt.(*nodeContext).processComprehension(0x886d3674908, 0x886da68ce48, 0x0)
/home/mvdan/src/c/cue/internal/core/adt/comprehension.go:342 +0xf7 fp=0x886da68ce10 sp=0x886da68cca8 pc=0x87cb97
cuelang.org/go/internal/core/adt.processComprehension(0x886d36017e0?, 0x886d36630e0, 0xe0?)
/home/mvdan/src/c/cue/internal/core/adt/tasks.go:239 +0xad fp=0x886da68ceb8 sp=0x886da68ce10 pc=0x8b6f6d
cuelang.org/go/internal/core/adt.runTask(0x886d36630e0, 0x2)
/home/mvdan/src/c/cue/internal/core/adt/sched.go:710 +0x671 fp=0x886da68d130 sp=0x886da68ceb8 pc=0x8b2fd1
[...]
I tried recreating this panic with the old aliases, like with #Def: z={, but I failed.
OK, Marcel shows that this panic also exists with old aliases:
exec cue export in.cue
-- in.cue --
z=#Def: {
_,
_out: {
if (z & string) != _|_ {
str: true
},
}
}
out: #Def & "foo"
And even with no aliases:
exec cue export in.cue
-- in.cue --
#Def: {
_,
_out: {
if (#Def & string) != _|_ {
str: true
},
}
}
out: #Def & "foo"
Lowering the priority given that it's not a new bug triggered by new aliases. I also forgot to mention that this was reported by @the-nurk on Slack.
not a stack overflow, but also self/value-alias related?
https://cuelang.org/play/?id=9Z-kVEjnmJg#w=function&i=cue&f=export&o=cue
@experiment(aliasv2)
import ("text/template")
// test only works with manual placement of k and not with alias on _#h.data.
// i can't place on the embed and use _#h for output
test: { [string]~(k,_): {#type, "\(k)"} //, _#h: data: "\(k)"} // commented out _#h and use #type~x
b: _
}
types: [for it,v in test {"\(it)": v._#h.exec}]
#type~x: { // aliased
//#type: {
string
_#h: {
exec: [if _data && _templ {template.Execute(templ, data)},{string}][0]
templ: """
{{ . }}?: _
_{{ . }}?: _
#{{ . }}?: _
_#{{ . }}?: _
#{{ . }}s?: _
_#{{ . }}s?: _
_{{ . }}s?: _|_
{{ . }}s?: _|_
"""
_templ: templ != _|_
_data: data != _|_
// dont work
// data: x
data: x & matchN(1, [string]) | error("bad input \(x)")
// data: [if ((x & string) != _|_) {x}, {string}][0] // no idea why this doesn't work
// data: [if (x & matchN(1,[string])) != _|_ {x}, {_}][0]
// data: string
}
}