Skip to content

Apply declared field values in Rust and C constructors [patch] - #219

Open
matt-edmondson wants to merge 1 commit into
mainfrom
fix/193-rust-c-constructor-field-defaults
Open

matt-edmondson wants to merge 1 commit into
mainfrom
fix/193-rust-c-constructor-field-defaults

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #193

What was wrong

Since #187, Go's constructors set every instance field that has an InitialValue and that the constructor doesn't set itself. The Rust and C generators have the same constructor shape but were never changed:

  • Rust built Self { … } from the initialisers only. A declared field the constructor didn't name was missing from the literal, which fails with E0063. A constructor with no initialisers wrote Self::default() and lost the declared value.
  • C wrote { .member = … } from the initialisers only, or {0} when there were none. The member started at 0 even though the struct's own comment says // defaults to 5.

Change

  • Both generators now record which class is having its functions written, the same way Go's _instanceFieldDefaults does. A constructor adds each instance field that has a declared value and that it doesn't set itself. The list comes from StandardLanguageGenerator.InstanceInitialised, so static and constant fields are excluded.
    • Rust: each such field goes into the Self { … } literal.
      • With no initialisers and no declared values, the output is still Self::default().
      • With no initialisers and declared values that don't cover every field (or a type with a base), the output is Self { count: 5, ..Self::default() }. The undeclared fields still come from Default, as they did before.
      • When the declared values cover every field, the literal stands alone and needs no Default.
    • C: each such field goes into the designated initialiser. Any member not named is zeroed, as before. {0} is still written when there is nothing to name. The struct's defaults to note is now true.
  • Constructors with explicit initialisers for every field are unchanged.

Tests (ConstructorFieldDefaultTests)

Three types, compiled with rustc and with cc -std=c11 -Wall -Wextra -pedantic, then run by a driver that reads every field back:

  • Counter: count = 5 plus a constructor that sets only step.
  • Settings: every field declared, and a constructor with no initialisers.
  • Mixed: one declared field, one undeclared field, and a constructor with no initialisers. In Rust the driver supplies impl Default, and step must come from it. In C, step must be zero.

With the generator changes reverted, both tests fail. Rust gives E0063: missing field 'count', and the C driver exits 1 because count reads 0. With the changes, both pass. Full Coder.Test suite: 1192 passed, 0 failed.

Out of scope: #202, where a type with no constructor drops the value in Rust (that one needs a design decision), and #178 / #169, which touch the same constructor paths.

🤖 Generated with Claude Code

https://claude.ai/code/session_012KjGQ13RexM4WYjuEaBtE6


Generated by Claude Code

A Rust or C constructor that did not set a field with an InitialValue
left it out: Rust's struct literal failed with E0063 (or fell back to
Self::default(), losing the value), and C started the member at 0 despite
its "defaults to" note. Both now add each such field to the literal or
designated initialiser, as Go does since #187, including when the
constructor has no initialisers. In Rust, a constructor with no
initialisers that still leaves a field undeclared fills the rest with
..Self::default(), as it relied on Default before.

Fixes #193

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012KjGQ13RexM4WYjuEaBtE6
@sonarqubecloud

Copy link
Copy Markdown

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.

Rust and C constructors drop instance-field initialisers: Rust fails with E0063 and C silently starts the field at 0

2 participants