Allow reordered record primary constructor assignments - #4052
Allow reordered record primary constructor assignments#4052sonyps5201314 wants to merge 1 commit into
Conversation
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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
|
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. |
Related to #4049.
Problem
RecordDecompiler.IsPrimaryConstructorimplicitly 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 invalidbase._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.RecordsRoslyn 3-or-newer configurations. Before the implementation, the new record was emitted with an explicit constructor andbase._002Ector().After the implementation:
PrettyTestRunner.Records: 6 passed, 0 failed.Release|Any CPUsolution build: 16 succeeded, 0 failed.BuildTools/format.ps1: clean.