Skip to content

Merge duplicate constant declarations into a union type#461

Merged
sinsoku merged 1 commit into
ruby:masterfrom
pvcresin:merge-duplicate-constant-declarations
Jun 21, 2026
Merged

Merge duplicate constant declarations into a union type#461
sinsoku merged 1 commit into
ruby:masterfrom
pvcresin:merge-duplicate-constant-declarations

Conversation

@pvcresin

@pvcresin pvcresin commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

When a constant is assigned more than once, Service#dump_declarations
emitted one declaration line per assignment, so

class C
  D = 1
  D = "str"
end

was dumped as two declarations for the same constant:

class C
  D: Integer
  D: String
end

This deduplicates constant writes by their static cpath so that each
constant yields a single declaration, and shows the union of its types
when it is assigned more than once:

class C
  D: (Integer | String)
end

A single assignment keeps using the assigned value (node.ret) rather
than the constant entity's type, so that a same-named class or module
(e.g. one declared in RBS) is not mixed into the declaration; see
scenario/rbs/remove-class.rb, where C = 1 coexists with an RBS
class C and the declaration is expected to stay C: Integer. The
deduplication mirrors the existing seen_ivars/seen_cvars/seen_gvars
handling in the same method.

scenario/known-issues/multi-const-write.rb now passes and is promoted
to scenario/const/. scenario/variable/operator_write.rb is updated
since it previously encoded the duplicated output (D = 0; D += 1 and
C::E = 0; C::E += 1 now each produce a single line).

All 429 tests pass (bundle exec rake test).

@pvcresin pvcresin force-pushed the merge-duplicate-constant-declarations branch from bdd119c to 23af2a2 Compare June 16, 2026 12:51
When a constant was assigned more than once (e.g. `D = 1; D = "str"`),
`Service#dump_declarations` emitted one declaration line per assignment,
so the same constant appeared multiple times (`D: Integer` followed by
`D: String`).

Deduplicate constant writes by their static cpath so that each constant
yields a single declaration, and show the union of its types
(`D: (Integer | String)`) when it is assigned more than once. A single
assignment keeps using the assigned value (`node.ret`) rather than the
constant entity's type, so that a same-named class or module (e.g. one
declared in RBS) is not mixed into the declaration; see
scenario/rbs/remove-class.rb. The deduplication mirrors the existing
seen_ivars/seen_cvars/seen_gvars handling in the same method.

Promote scenario/known-issues/multi-const-write.rb to scenario/const/ and
update scenario/variable/operator_write.rb, which previously encoded the
duplicated output.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pvcresin pvcresin force-pushed the merge-duplicate-constant-declarations branch from 23af2a2 to 093ecd3 Compare June 16, 2026 13:01

@sinsoku sinsoku left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good!

@sinsoku sinsoku merged commit f0760f1 into ruby:master Jun 21, 2026
6 checks passed
@pvcresin pvcresin deleted the merge-duplicate-constant-declarations branch June 21, 2026 09:16
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.

2 participants