Skip to content

Keep Go constant-field values and apply instance-field initialisers - #187

Merged
matt-edmondson merged 2 commits into
mainfrom
fix/111-go-constant-and-initialised-fields
Oct 7, 2026
Merged

matt-edmondson merged 2 commits into
mainfrom
fix/111-go-constant-and-initialised-fields

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #111

What changed

GoGenerator decided where a field goes from IsStatic alone. Two things went wrong as a result:

  • A constant that wasn't static became a struct member, and its value was dropped.
  • An instance field's InitialValue was lost: the constructor returned Cfg{}.

The fix:

  • Constant fields. A new IsPackageLevelField returns field.IsStatic || field.IsConstant, matching RustGenerator.IsAssociatedField. Both placement predicates now use it, so Ratio is written as const CfgRatio float64 = 0.5, the same path static fields already take.
  • Instance-field initialisers. Each generated constructor now sets the initialised instance fields it doesn't set itself. For example, Cfg{Misses: 1, Hits: 5}: the constructor's own Misses: 1 wins over the field's default, and no key is written twice, since Go rejects duplicate keys.
  • Note on the field. The struct member gets a note, // defaults to 5: Go has no field initialisers, so only a constructor sets it, because a bare Cfg{} literal still starts the field at zero.

Tests

  • GoGeneratedSourceCompilesTests.ConstantAndInitialisedFields_KeepTheirValuesWhenRun runs the issue's reproduction with a real Go toolchain. go run . now prints 0.5 5; before the fix it printed 0 0. The test also checks that gofmt would leave the generated file unchanged.
  • GoGeneratorTests.Constructor_SetsInstanceFieldDefaultsItDoesNotSetItself covers a constructor that sets one field itself, plus the note on the field.
  • GoGeneratorTests.ConstantField_IsPackageLevelEvenWhenNotStatic covers a non-static constant.

With GoGenerator.cs reverted, all three fail; with the fix, they pass. The full suite passes locally (1091 tests, 0 failed, 0 skipped, with Go on the path).

🤖 Generated with Claude Code

https://claude.ai/code/session_01JgoVAth3nGZUgbKrSgVCYX


Generated by Claude Code

GoGenerator placed a field by IsStatic alone, so a constant that was not
static became a struct member and its value was dropped, and an instance
field's initialiser was lost from the generated constructor. A constant now
goes to package-level storage, as static fields already did and as Rust
does, and each constructor sets the initialised instance fields it does not
set itself. The struct member carries a note saying where its default is
applied, since a bare composite literal still starts it at zero.

Fixes #111

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JgoVAth3nGZUgbKrSgVCYX
Comment thread Coder/Languages/GoGenerator.cs Fixed
@sonarqubecloud

sonarqubecloud Bot commented Oct 7, 2026

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 9a1026b into main Oct 7, 2026
14 checks passed
@matt-edmondson
matt-edmondson deleted the fix/111-go-constant-and-initialised-fields branch October 7, 2026 05:36
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.

Go silently drops the value of a constant (non-static) field, and of every instance-field initializer: the struct is zero-valued

2 participants