Skip to content

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

Description

@matt-edmondson

What's wrong

#111 / #187 made Go's constructors set every instance field that declares an InitialValue and that the constructor does not set itself (Coder/Languages/GoGenerator.cs:1189-1197). The Rust and C generators have the same constructor shape and were not changed:

  • Rust: RustGenerator.WriteConstructorBody (Coder/Languages/RustGenerator.cs:1062-1082) builds Self { … } from funcDecl.Initialisers only. An initialised instance field the constructor doesn't name is left out of the struct literal, so rustc rejects it with E0063 ("missing field"). With no initialisers at all it writes Self::default(), so the declared default is lost there too.
  • C: CGenerator.GenerateConstructorBody (Coder/Languages/CGenerator.cs:276-302) writes { .member = … } from funcDecl.Initialisers only, or {0} when there are none, so the field starts at 0 — while the struct member carries the comment // defaults to 5 (CGenerator.cs:680), which says the opposite.

C++, C#, JavaScript, Python and (since #187) Go all honour the default.

Reproduction (verified with rustc and gcc)

ClassDeclaration("Counter") with field count: int = 5, field step: int, and a constructor (int s) with initialiser step = s.

Rust output:

pub fn new(s: i32) -> Self {
    Self { step: s }
}

→ error[E0063]: missing field 'count' in initializer of 'Counter'.

C output:

typedef struct Counter
{
    int count;  // defaults to 5
    int step;
} Counter;

Counter Counter_create(int s)
{
    Counter self = { .step = s };
    return self;
}

→ Counter_create(1).count is 0. C++/C#/Go give 5.

Suggested fix / acceptance criteria

  • Mirror GoGenerator: for each initialised instance field a constructor doesn't name, add it to the Rust Self { … } literal and the C designated initialiser, including when the constructor has no initialisers (instead of Self::default() / {0}). StandardLanguageGenerator.InstanceInitialised can supply the list.
  • Add compile-and-run tests in RustGeneratedSourceCompilesTests and CGeneratedSourceCompilesTests for a type with an initialised field its constructor doesn't set; the field must read back its declared value.
  • Keep the C struct comment accurate (say the constructor applies the default, or drop it).

Activity

  1. matt-edmondson commented on Oct 7, 2026

    @matt-edmondson
    ContributorAuthor

    Triage


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions