Parsing of table literal as an argument is inconsistent
Describe the bug
It appears that parsing of the header form of table literals is incorrect for at least the table argument of the join command. Perhaps this happens for other commands, too?
How to reproduce
Run this script:
use std assert
# start figuring out the relation between islands in Riven :grin:
let list_of_records = [{"island name": boiler}]
let table = [["island name"]; [boiler]]
assert ($list_of_records == $table)
assert (($list_of_records | join $list_of_records "island name") == $table)
assert (($table | join $list_of_records "island name") == $table)
assert (($table | join ([{"island name": boiler}]) "island name") == $table)
assert (($table | join [{"island name": boiler}] "island name") == $table)
assert (($table | join $table "island name") == $table)
assert (($table | join ([["island name"]; [boiler]]) "island name") == $table)
assert (($table | join [["island name"]; [boiler]] "island name") == $table) # fails :'(
Expected behavior
The final line:
assert (($table | join [["island name"]; [boiler]] "island name") == $table) # fails :'(
…should not fail its assert call.
Screenshots
No response
Configuration
| key | value |
|---|---|
| version | 0.96.1 |
| major | 0 |
| minor | 96 |
| patch | 1 |
| branch | |
| commit_hash | |
| build_os | macos-aarch64 |
| build_target | aarch64-apple-darwin |
| rust_version | rustc 1.79.0 (129f3b996 2024-06-10) (Homebrew) |
| cargo_version | cargo 1.79.0 |
| build_time | 2024-07-29 23:31:36 +00:00 |
| build_rust_channel | release |
| allocator | mimalloc |
| features | default, sqlite, system-clipboard, trash |
| installed_plugins |
Additional context
No response
I wonder if this could be a bug with join too because this doesn't return anything.
$table | join [["island name"]; [boiler]] "island name"
It is interesting that this works though, as if the table literal needs to be in parens for proper evaluation.
($table | join ([["island name"]; [boiler]]) "island name") == $table
I'm on mobile, so I can't get dumo the info, but if you run nu --ide-ast on the script, the unparenthesized table literal appears to be parsed as a list? 👀 The parenthesized literal right before it works fine.
hmmm, interesting. I forgot about --ide-ast. I wonder what the IR says.
❯ view ir { $table | join [["island name"]; [boiler]] "island name" }
# 4 registers, 13 instructions, 22 bytes of data
0: load-variable %0, var 4209 "$table"
1: load-literal %1, list(capacity = 1)
2: load-literal %2, list(capacity = 1)
3: load-literal %3, string("island name")
4: list-push %2, %3
5: list-push %1, %2
6: load-literal %2, string("island name")
7: push-positional %1
8: push-positional %2
9: redirect-out caller
10: redirect-err caller
11: call decl 81 "join", %0
12: return %0
❯ view ir { $table | join ([["island name"]; [boiler]]) "island name" }
# 6 registers, 16 instructions, 28 bytes of data
0: load-variable %0, var 4209 "$table"
1: load-literal %1, list(capacity = 1)
2: load-literal %2, string("island name")
3: load-literal %3, record(capacity = 1)
4: clone %4, %2
5: load-literal %5, string("boiler")
6: record-insert %3, %4, %5
7: list-push %1, %3
8: drop %2
9: load-literal %2, string("island name")
10: push-positional %1
11: push-positional %2
12: redirect-out caller
13: redirect-err caller
14: call decl 81 "join", %0
I think this reveals two underlying issues:
- maybe the
parse_valueListarm should actually callparse_table_expression(see #14226) - the data is partially parsed due to missing checks in
parse_list_expression(a quick-and-dirty fix is described at https://github.com/nushell/nushell/issues/14188#issuecomment-2445394490)