Skip to content

Allow reordered record primary constructor assignments - #4052

Closed
sonyps5201314 wants to merge 1 commit into
icsharpcode:masterfrom
sonyps5201314:split/reordered-record-primary-constructor
Closed

Allow reordered record primary constructor assignments#4052
sonyps5201314 wants to merge 1 commit into
icsharpcode:masterfrom
sonyps5201314:split/reordered-record-primary-constructor

Conversation

@sonyps5201314

Copy link
Copy Markdown
Contributor

Related to #4049.

Problem

RecordDecompiler.IsPrimaryConstructor implicitly required assignments to positional auto-properties to follow primary-constructor parameter order.

That is not guaranteed: explicit positional properties can be declared in a different order, so their backing-field assignments follow member initialization order instead. In that case ILSpy failed to recognize the primary constructor and emitted an explicit constructor, synthesized Deconstruct, and an invalid base._002Ector() call.

Solution

Validate each assignment against the parameter actually loaded by that assignment, without carrying a monotonic parameter index between assignments.

This PR intentionally contains only the record primary-constructor fix and its regression test. It does not include collection expressions, project export/resolution changes, record synthesized-member changes, or unrelated backing-field fixes from #4049.

Test

The test was added first and failed in all six PrettyTestRunner.Records Roslyn 3-or-newer configurations. Before the implementation, the new record was emitted with an explicit constructor and base._002Ector().

After the implementation:

  • PrettyTestRunner.Records: 6 passed, 0 failed.
  • Full Release|Any CPU solution build: 16 succeeded, 0 failed.
  • BuildTools/format.ps1: clean.
  • At least one test covering the code changed

Record primary constructor detection incorrectly required auto-property assignments to follow parameter order, but metadata order follows member initialization order. Track each assignment using its actual parameter instead.

Assisted-by: Codex:gpt-5.6-sol:Codex
public string D = A + B;
}
#if EXPECTED_OUTPUT
public record PrimaryCtorWithReorderedPropertyInitializers(int First, int Second);

@siegfriedpammer siegfriedpammer Aug 26, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why should this be the expected output? The user wrote explicit auto properties, so we should keep them verbatim. The check for monotonically increasing parameterIndex values you deleted was deliberate.

The decompiler is supposed to produce C# code that matches the underlying IL as closely as possible. That is one of the core goals of ILSpy. We are not going to change that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You are right. I misunderstood the purpose of the monotonic parameterIndex check: the reversed initialization order is evidence that these are explicit auto-properties, so collapsing them into synthesized positional properties would lose source/IL fidelity. The expected output in my test was therefore wrong, and removing the check moves the decompiled result away from ILSpy's core goal.

I will close this PR instead of trying to preserve that normalization. The broader reference branch will remain available, but this change will not be proposed for merging. Thank you for the clarification.

@christophwille

Copy link
Copy Markdown
Member

I know it is closed already, but I have to point to https://github.com/icsharpcode/ILSpy/blob/master/CONTRIBUTING.md, especially bullet number two.

Please don't create PRs if you cannot validate what the clanker hands you. We'd much rather have you write a concise, in-your-own voice bug report and then we can sit down with our clanker and steer her to a proper solution. This PR is an example where we remote-steer your clanker without seeing the entire conversation, and that is just highly impractical - and overly time-consuming (after all, we are a 100% free time operation).

So please if you don't know your ways around our architecture, please do consider switching to spending your time on great reports of features that don't work the way they should. Shifting all responsibility on us the reviewers is not going to fly, I hope you understand that.

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.

3 participants