Skip to content

Review fix legend pure compiler mismatch - #4997

Closed
FeruzGS wants to merge 3 commits into
finos:masterfrom
goldmansachs:review-fix-legend-pure-compiler-mismatch
Closed

Review fix legend pure compiler mismatch#4997
FeruzGS wants to merge 3 commits into
finos:masterfrom
goldmansachs:review-fix-legend-pure-compiler-mismatch

Conversation

@FeruzGS

@FeruzGS FeruzGS commented Jul 29, 2026

Copy link
Copy Markdown

Purpose

Aligns Legend Java compiler's handling of single-element collection literals

([$x]) with Pure's own compiler. Previously, wrapping any non-[1] variable

in brackets — e.g. [$optional] where $optional : String[0..1] — was

rejected by ValueSpecificationBuilder.visit(Collection) with:

Collection element must have a multiplicity [1] ... multiplicity:[0..1]

Reproduction (before fix)

function test::f(opt:String[0..1], many:String[*]):String[*]

{

   concatenate([$opt], $many)

}
  • Pure IDE: compiles

  • Legend compiler: [Error] "Collection element must have a multiplicity [1] ... [0..1]"

Fix

In ValueSpecificationBuilder.visit(Collection):

  1. Guard relaxed to multi-element case only. The [1]-only element rule

    now fires only when collection.values.size() > 1. Single-element literals

    [$x] are accepted regardless of the wrapped variable's multiplicity —

    they act as a semantically transparent wrapper (Pure has no nested

    collections; [$x] and $x produce the same flat shape).

  2. Effective multiplicity propagated truthfully. For a 1-element literal

    wrapping a non-[1] variable, the resulting InstanceValue's multiplicity

    is set to the inner variable's multiplicity (not the parser-supplied count

    of 1). This ensures downstream consumers see the real runtime cardinality

    rather than being told "exactly 1" when the value could be [0..1] or

    [*].

  3. Unwrap guarded by isExactlyOne. The value-compaction step (unwrap a

    single-element InstanceValue into its raw first value) now only fires

    when the element's multiplicity is exactly [1].

For every collection shape that compiled before this change, the resulting

M3 graph is byte-identical. Only newly-accepted shapes produce a new graph,

and that graph matches what Pure's own compiler produces from equivalent

.pure source.

Patterns unblocked

All five surface syntaxes that lower to visit(Collection):

  1. Function argumentsconcatenate([$opt], $many) (the ticket case).

  2. if branchesif($cond, | [$opt], | []).

  3. Class constructor slots^Foo(xs = [$opt]) where xs : String[*].

  4. Pipeline steps$people->filter(p | [$p.middleName]->isNotEmpty()).

Invariant preserved

Multi-element literals [a, b, ...] still require every element to be [1].

This is the invariant that parser-rewritten binary operators rely on:

$a + 'x'  →  plus([$a, 'x'])   -- 2-element, still strict-checked

Files changed

  • ValueSpecificationBuilder.java — the fix (+ isExactlyOne helper).

  • TestDomainCompilationFromGrammar.java — 5 regression tests.

@FeruzGS
FeruzGS requested a review from a team as a code owner July 29, 2026 12:47
@github-actions

Copy link
Copy Markdown

Test Results

  1 026 files    1 026 suites   3h 8m 8s ⏱️
16 866 tests 16 695 ✔️ 171 💤 0
36 976 runs  36 805 ✔️ 171 💤 0

Results for commit 46104b2.

@FeruzGS FeruzGS closed this Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant