Parent: #366. Found by the builtin probe in #370 (gap fold-after-coercion).
Goal
Make builtin folds see the literal the author wrote, as the pinned OverPy 9.7.10 does, instead of the parameter's canonical form.
Context
Lowering rewrites False, True, 0 and an empty array to the parameter's canonical form (normalize_value_with_coercions in compiler/lowering.rs) before optimization. A fold on the rewritten value then differs from the reference, which folds on what was written: min(false, 3) folds to 0 natively but stays Min(False, 3); [1, 2].index(0) keeps Null natively but folds to -1; hudText(..., [], ...) becomes Null; .replace, .slice behave alike. 38 probes (6 functions) differ; after workshop-rs 0.6.4 parsing treats the coercible spellings as one structure, so only the folds show.
Scope
- Apply the coercions after optimization, or stop applying them where the validator now accepts the authored form, without changing the structure of currently converged output.
- Oracle-backed fixtures for the folds above.
Non-goals
Acceptance criteria
Parent: #366. Found by the builtin probe in #370 (gap
fold-after-coercion).Goal
Make builtin folds see the literal the author wrote, as the pinned OverPy 9.7.10 does, instead of the parameter's canonical form.
Context
Lowering rewrites
False,True,0and an empty array to the parameter's canonical form (normalize_value_with_coercionsincompiler/lowering.rs) before optimization. A fold on the rewritten value then differs from the reference, which folds on what was written:min(false, 3)folds to0natively but staysMin(False, 3);[1, 2].index(0)keepsNullnatively but folds to-1;hudText(..., [], ...)becomesNull;.replace,.slicebehave alike. 38 probes (6 functions) differ; after workshop-rs 0.6.4 parsing treats the coercible spellings as one structure, so only the folds show.Scope
Non-goals
Acceptance criteria
fold-after-coerciongap is removed fromtools/overpy/probe-gaps.json.integration_testsand the corpus stay green (12 semantic-equivalence tests depend on today's normalization).