Including some field inside a record whose name is the same of the included field causes Nickel to hang indefinitely
Describe the bug Consider this code snippet:
{
data = { some_field = "asd" },
inner = {
data = { include data }
}
}
If I run nickel eval on this file, the command never ends and it hangs without outputting any error message.
To Reproduce
Save the snippet above to a .ncl file and try to evaluate it using the Nickel cli.
Expected behavior The Nickel evaluation should succede or exit with an error, not hang.
Environment
- Windows 11
- Nickel v1.12.0
This produces an infinite data structure, because it evaluates to
{
data = { some_field = "asd" },
inner = {
data = { data = { data = { ... } } }
}
}
The data = { some_field = "asd" } line is irrelevant, because at the "include data" part, the name "data" refers to the "data" field of the "inner" record.
Makes sense. Is it intended behavior that Nickel doesn't catch this and hangs?
It was discussed in #1815. I think the conclusion is that we can probably catch this. It isn't completely trivial, because infinite data structures are allowed in a lazy language like nickel. So we can't forbid this kind of recursion, we just have to detect if you're trying to evaluate it fully.
While some infinite recursions are nasty to detect (well, it's the halting problem in the general case, so...), I agree we should catch those kind of direct, obvious infinite recursions. As far as I remember, we already had a solution in https://github.com/tweag/nickel/pull/2055, and in fact implemented the thunk-based locking; so it's mostly a matter of re-using the same mechanism for general eval.