Skip to content

Detect line-level local-variable duplication inside spliced function bodies - #34

Merged
TheValiantOne merged 1 commit into
mainfrom
fix/local-var-dup-invariant
Aug 11, 2026
Merged

Detect line-level local-variable duplication inside spliced function bodies#34
TheValiantOne merged 1 commit into
mainfrom
fix/local-var-dup-invariant

Conversation

@TheValiantOne

Copy link
Copy Markdown
Owner

Summary

The last compile error standing after the v0.6.3 pristine live merge: Variable 'mCSMCR' is already defined in merged combat.ws — DiffPlex's silent-duplication mode striking at line granularity, duplicating a mod's comment-wrapped local declaration block inside a function body. Every unit-level invariant from #33 passes such output (unit counts are all correct); the game's compiler doesn't.

Fix

  • HasDuplicatedLocalVarDecls: counts local var declarations per name inside a unit's text (comment-stripped so commented-out declarations don't skew; multi-declarator lines count each name). The merged unit may never declare a local more often than every input version of the same unit — duplication an input already carried is tolerated (same only-flag-what-the-merge-introduced philosophy as the unit-count invariants).
  • Wired into both splice sites: ValidateWholeFileMergeOutput (per matched scoped unit — a corrupt whole-file "clean" step now routes to the function-level rescue) and ResolveUnit's per-function 3-way path (a corrupt per-function splice falls back to the whole-function tiebreak, with an audit note naming the duplicated local).

Validation

3 new tests: the exact combat.ws shape detected; pre-existing input duplicates tolerated; commented-out declarations ignored. 156 total, green; format clean. Live re-merge of the affected file with this build posted below once run.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GXAuGMLB44T5Zv5o5ZzKah

…bodies

DiffPlex's silent-duplication failure mode operates at line granularity
too: a clean-looking splice inside a function body can duplicate a local
declaration - invisible to every unit-level count invariant, fatal at
compile ("Variable 'mCSMCR' is already defined", observed live in a
freshly merged combat.ws whose comment-wrapped mod declaration block was
emitted twice).

- New HasDuplicatedLocalVarDecls: per-unit local `var` declaration counts
  (comment-stripped, multi-declarator aware) - the merged unit may never
  declare a local more often than every input version of that unit does.
  Pre-existing input duplicates are tolerated (only merge-INTRODUCED
  duplication flags).
- Wired into ValidateWholeFileMergeOutput (per matched scoped unit, so a
  silently-corrupt whole-file "clean" step routes to the rescue) and into
  ResolveUnit's per-function 3-way path (a corrupt splice falls back to
  the whole-function tiebreak, with a decision note).

3 new tests (156 total).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GXAuGMLB44T5Zv5o5ZzKah
@TheValiantOne

Copy link
Copy Markdown
Owner Author

Live repair confirmed

Re-merged the affected combat.ws on the real install with this branch's build. Two-step finding worth recording: the first overwrite re-merge kept the duplicate — correctly, because the corrupted merged file re-enters the chain as the accumulated source, making the duplicate a pre-existing input duplicate the invariant deliberately tolerates. The actual repair required a pristine chain for that file (drop its inventory record + delete the corrupted output, then merge vanilla+mods) — after which: exactly one var mCSMCR declaration, all usages intact, structural gate passes, output self-consistent under the full validator, 0 decisions needed (clean per-function resolution).

Practical takeaway for users hitting merge-corrupted output from older builds: refreshing with overwrite faithfully preserves the corruption (it's in the input); the fix is removing that file's merged output + inventory record and re-merging fresh. Worth a docs note when this merges.

🤖 Generated with Claude Code

@TheValiantOne
TheValiantOne merged commit bc88385 into main Aug 11, 2026
1 check passed
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