fix(parser)!: preserve contextual literal substitutions - #300
Merged
Merged
Conversation
Catalog coercion facts now decide only which literal substitutions a parameter accepts. The parser keeps the authored literal, so parsing and emitting Workshop text no longer rewrites False/True to 0/1, 0 or a zero vector to Null, or Empty Array to an empty string, and the result no longer depends on which identity a locale spelling resolves to. BREAKING CHANGE: Program and round-trip equivalence now distinguish 0 from False, 1 from True, and 0 or Vector(0, 0, 0) from Null at coerced positions. ADR-0015 records the decision; docs/element-count.md records that the element cost of these substitutions has no client evidence. Fixes #298
This was referenced Sep 26, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Catalog coercion facts now decide only which literal substitutions a parameter accepts; the parser keeps the authored literal. Parse → emit no longer rewrites
False/True→0/1,0/Vector(0, 0, 0)→Null, orEmpty Array→"".normalize_contextual_argument,normalize_modify_value,normalize_modify_call_value) from value, assignment, and modify parsing. Validation already accepted the authored forms viacontextual_value_matches, so acceptance is unchanged.optimizeForSizestaysopy-rspolicy, which can now write the substituted form intoProgramitself.docs/element-count.mdrecords the evidence gap: no client capture establishes whether a numeric literal andFalse/True/Nullcost the same. The model is unchanged; the analysis now sees the authored literal and can apply whatever rule a capture establishes.Behavior change
Programand round-trip equivalence now distinguish0fromFalse,1fromTrue, and0/zero vector fromNullat coerced positions (marked breaking). Consumers that compared against normalized output (e.g.opy-rsreference comparisons) adopt this in their own PRs.Client evidence
None available: no capture of the element cost of
0versusFalsein a numeric argument exists. The ADR-0005 capture is follow-up work and does not change this decision.Verification
cargo fmt --all --check,cargo clippy --workspace --all-targets -- -D warnings,cargo test --workspace --all-targets(all pass),workshop-catalog-gen -- check,git diff --check.contextual_aliases_survive_parse_and_emit_in_each_locale: the Decide whether parsing may discard OverPy optimizeForSize literal substitutions #298 table spellings survive en-US parse → emit verbatim, and a zh-CN emit → parse → emit is stable and equivalent to the authored program.OWBastion/BastionWright build comparison, which needs theopy-rsadoption.Fixes #298