Represent array and list literals with spreads with a Pexp_spread node
๐
Polish๐ Bug fix๐ Internalsyntaxprintertypecheckerlambdacodegenanalysisreanalyzetests
The parser no longer turns [a, ...b] and list{...a, b} into calls of Primitive_array.spread and Primitive_list.spread marked with res.spread. Pexp_spread keeps the items and spreads in source order, and the type checker gives it a Texp_spread node. Translation emits new Parray_spread and Plist_spread primitives that compile to the same runtime calls. A list literal whose only spread is its tail stays a chain of ::.
let x = [...[1, 2], 3, ...[]]let y = @attr list{...xs, ...list{}, 1}
let x = [...[1, 2], 3, ...[]]let y = @attr list{...xs, ...list{}, 1}
Source the old formatter printed [1, 2, 3, ] and list{...xs, , 1} without the attribute; the new one prints the input unchanged (tests/syntax_tests/data/printer/expr).
๐
PolishReport a spread of the wrong collection type, such as a list spread into an array, as a mismatch of the spread instead of an array item.
๐ Bug fixFix the formatter dropping spreads of array and list literals, attributes on literals with spreads, and comments in list literals with spreads.
๐ InternalRepresent array and list literals with spreads with a dedicated parsetree node.
Review
- Why do the generated item groups have ghost locations? The v0 encoding has no marker on them, and the ghost flag tells a group of items from an array or list literal that is spread. A call built by a PPX with real locations decodes to spreads only, which concatenates the same values.
- Why does the typed node hold the concatenated parts rather than the elements? The parts are the arrays and cons chains the runtime call takes, so the items keep the errors of array and list literals and translation needs no list building of its own.
- Output
- unchangedtests/tests JS byte-identical after a rebuild; a combinatorial harness of all item/spread sequences up to length 4 compiles to identical JS with the old and new bsc
- Formatting
- changedspreads of array and list literals and attributes on literals with spreads are kept; comments in list spreads stay in place
- Formats
- astcmt
- PPX
- unchangedwire: the v0 encoding is the res.spread call it was, decoded back to Pexp_spread (ast-mapping fixture SpreadLiterals.res)
- Editor
- unchanged:pipe completion types the literal as the runtime call; SpreadLiterals.res covers AST dump, hints, highlighting and completion
- Tests
- syntax
tests/syntax_tests/data/+ ast-mapping/SpreadLiterals.res~ printer/expr/array.res~ printer/expr/list.res~ printer/comments/array.resanalysis+ tests/analysis_tests/tests/src/SpreadLiterals.ressuper_errorstests/build_tests/+ super_errors/fixtures/array_spread_type_mismatch.res+ super_errors/fixtures/list_spread_type_mismatch.res+ super_errors/fixtures/array_spread_annotation_mismatch.resounittests/ounit_tests/~ ounit_ast_mapper0_tests.ml
- Changelog fragment changes/spread-literal-errors.polish.md
- Changelog fragment changes/spread-literal-formatting.fix.md
- Changelog fragment changes/spread-literal-node.internal.md
- No committed generated JS changes
- Magic numbers bumped: ast_impl ResImpl01318, ast_intf ResIntf01318, cmt Caml1999T046
- v0 PPX bridge changes; ast-mapping fixture or mapper unit test in the diff
61 files ยท +761 โ294 ยท reanalyze 2 ยท analysis 5 ยท changelog 3 ยท lambda 2 ยท compiler 1 ยท typechecker 23 ยท syntax 5 ยท tests 20
| M | analysis/reanalyze/src/arnold.ml | +2 | โ0 |
| M | analysis/reanalyze/src/side_effects.ml | +2 | โ0 |
| M | analysis/src/completion_front_end.ml | +12 | โ0 |
| M | analysis/src/dump_ast.ml | +17 | โ0 |
| M | analysis/src/hint.ml | +4 | โ3 |
| M | analysis/src/semantic_tokens.ml | +0 | โ8 |
| M | analysis/src/utils.ml | +1 | โ0 |
| A | changes/spread-literal-errors.polish.md | +1 | โ0 |
| A | changes/spread-literal-formatting.fix.md | +1 | โ0 |
| A | changes/spread-literal-node.internal.md | +1 | โ0 |
| M | compiler/core/lam_analysis.ml | +2 | โ1 |
| M | compiler/core/lam_compile_primitive.ml | +2 | โ0 |
| M | compiler/ext/config.ml | +3 | โ3 |
| M | compiler/ml/ast_helper.ml | +1 | โ0 |
| M | compiler/ml/ast_helper.mli | +2 | โ0 |
| M | compiler/ml/ast_iterator.ml | +5 | โ0 |
| M | compiler/ml/ast_mapper.ml | +7 | โ0 |
| M | compiler/ml/ast_mapper_from0.ml | +49 | โ0 |
| M | compiler/ml/ast_mapper_to0.ml | +6 | โ0 |
| A | compiler/ml/ast_spread.ml | +95 | โ0 |
| M | compiler/ml/depend.ml | +5 | โ0 |
| M | compiler/ml/lambda.ml | +6 | โ0 |
| M | compiler/ml/lambda.mli | +4 | โ0 |
| M | compiler/ml/parsetree.ml | +11 | โ0 |
| M | compiler/ml/pprintast.ml | +11 | โ0 |
| M | compiler/ml/printast.ml | +14 | โ0 |
| M | compiler/ml/printlambda.ml | +2 | โ0 |
| M | compiler/ml/printtyped.ml | +6 | โ0 |
| M | compiler/ml/rec_check.ml | +6 | โ4 |
| M | compiler/ml/tast_iterator.ml | +1 | โ0 |
| M | compiler/ml/tast_mapper.ml | +2 | โ0 |
| M | compiler/ml/translcore.ml | +8 | โ0 |
| M | compiler/ml/typecore.ml | +29 | โ0 |
| M | compiler/ml/typedtree.ml | +3 | โ0 |
| M | compiler/ml/typedtree.mli | +3 | โ0 |
| M | compiler/ml/typedtree_iter.ml | +1 | โ0 |
| M | compiler/syntax/src/res_comments_table.ml | +9 | โ24 |
| M | compiler/syntax/src/res_core.ml | +29 | โ95 |
| M | compiler/syntax/src/res_parsetree_viewer.ml | +0 | โ27 |
| M | compiler/syntax/src/res_parsetree_viewer.mli | +0 | โ7 |
| M | compiler/syntax/src/res_printer.ml | +27 | โ114 |
| A | tests/analysis_tests/tests/src/SpreadLiterals.res | +20 | โ0 |
| A | tests/analysis_tests/tests/src/expected/SpreadLiterals.res.txt | +119 | โ0 |
| A | tests/build_tests/super_errors/expected/array_spread_annotation_mismatch.res.expected | +16 | โ0 |
| A | tests/build_tests/super_errors/expected/array_spread_type_mismatch.res.expected | +11 | โ0 |
| A | tests/build_tests/super_errors/expected/list_spread_type_mismatch.res.expected | +11 | โ0 |
| A | tests/build_tests/super_errors/fixtures/array_spread_annotation_mismatch.res | +4 | โ0 |
| A | tests/build_tests/super_errors/fixtures/array_spread_type_mismatch.res | +4 | โ0 |
| A | tests/build_tests/super_errors/fixtures/list_spread_type_mismatch.res | +4 | โ0 |
| M | tests/ounit_tests/ounit_ast_mapper0_tests.ml | +95 | โ0 |
| A | tests/syntax_tests/data/ast-mapping/SpreadLiterals.res | +15 | โ0 |
| A | tests/syntax_tests/data/ast-mapping/expected/SpreadLiterals.res.txt | +15 | โ0 |
| M | tests/syntax_tests/data/parsing/grammar/expressions/expected/array.res.txt | +5 | โ5 |
| M | tests/syntax_tests/data/parsing/grammar/expressions/expected/list.res.txt | +1 | โ1 |
| M | tests/syntax_tests/data/parsing/recovery/expression/expected/list.res.txt | +1 | โ2 |
| M | tests/syntax_tests/data/printer/comments/array.res | +9 | โ0 |
| M | tests/syntax_tests/data/printer/comments/expected/array.res.txt | +9 | โ0 |
| M | tests/syntax_tests/data/printer/expr/array.res | +12 | โ0 |
| M | tests/syntax_tests/data/printer/expr/expected/array.res.txt | +12 | โ0 |
| M | tests/syntax_tests/data/printer/expr/expected/list.res.txt | +4 | โ0 |
| M | tests/syntax_tests/data/printer/expr/list.res | +4 | โ0 |