Two used units could not export the same module-scope global var name:
the second Define raised "Duplicate identifier", and even where one slot
existed a qualified reference (Unit.V) was lowered by bare name, so it
could not pick a specific unit's storage. Bare references also resolved
through the flat table (analysis order) rather than the uses chain,
disagreeing with the last-in-uses rule that consts already follow.
Give vars the same cross-unit semantics as consts:
- DefineGlobalLastWins detaches the prior unit's var on a cross-unit
collision (keeping it alive in the per-unit cache so Unit.V still
reaches it) and installs the later unit as the flat winner; same-unit
redeclaration and module-name markers stay hard errors. RegisterVars
mirrors this on the prebuilt-import path, as RegisterConsts does.
- The analyser stamps the resolved owning unit onto each global-var
reference and assignment target (the uses-chain winner for a bare ref,
the named unit for a qualified one). Codegen mangles the storage
symbol with that owner instead of re-looking-up the bare name, so the
definition (keyed on the unit being compiled) and every reference
agree. A bare reference now follows uses order like a const; a
qualified reference always hits its own unit's slot.
Tests: e2e last-wins (+ reversed) and qualified disambiguation across two
units exporting `var V`, plus an IR-level check that qualified loads emit
distinct owner-prefixed symbols.