Skip to content

Commit 453fc06

Browse files
Fix #3406: Wrong decompilation of record struct without primary constructor.
1 parent 6a4ad27 commit 453fc06

File tree

5 files changed

+49
-3
lines changed

5 files changed

+49
-3
lines changed

ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@
135135
<Compile Include="TestCases\ILPretty\Issue3442.cs" />
136136
<Compile Include="TestCases\ILPretty\MonoFixed.cs" />
137137
<Compile Include="TestCases\Pretty\Comparisons.cs" />
138+
<Compile Include="TestCases\Pretty\Issue3406.cs" />
138139
<Compile Include="TestCases\Pretty\Issue3439.cs" />
139140
<Compile Include="TestCases\Pretty\Issue3442.cs" />
140141
<None Include="TestCases\VBPretty\VBAutomaticEvents.vb" />

ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,12 @@ public async Task Issue3439([ValueSource(nameof(defaultOptions))] CompilerOption
610610
await RunForLibrary(cscOptions: cscOptions);
611611
}
612612

613+
[Test]
614+
public async Task Issue3406([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)
615+
{
616+
await RunForLibrary(cscOptions: cscOptions);
617+
}
618+
613619
[Test]
614620
public async Task Issue3442([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
615621
{
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
internal class Issue3406
2+
{
3+
private record struct S1(int Value);
4+
5+
private record struct S2
6+
{
7+
public int Value;
8+
9+
public S2(int value)
10+
{
11+
Value = value;
12+
}
13+
14+
public S2(int a, int b)
15+
{
16+
Value = a + b;
17+
}
18+
}
19+
20+
private record struct S3
21+
{
22+
public int Value;
23+
24+
public S3(int value)
25+
{
26+
Value = value;
27+
}
28+
}
29+
30+
// This also generates a hidden backing field
31+
private record struct S4(int value)
32+
{
33+
public int Value = value;
34+
}
35+
}

ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,14 @@ bool IsPrimaryConstructor(IMethod method, IMethod unspecializedMethod)
222222
{
223223
backingMember = property;
224224
}
225-
else
225+
else if (!recordTypeDef.IsRecord)
226226
{
227227
backingMember = field;
228228
}
229+
else
230+
{
231+
return false;
232+
}
229233

230234
primaryCtorParameterToAutoPropertyOrBackingField.Add(unspecializedMethod.Parameters[i], backingMember);
231235
autoPropertyOrBackingFieldToPrimaryCtorParameter.Add(backingMember, unspecializedMethod.Parameters[i]);

ICSharpCode.Decompiler/CSharp/Transforms/TransformFieldAndConstructorInitializers.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,9 @@ bool IsPropertyDeclaredByPrimaryCtor(IMember m, RecordDecompiler record)
285285
case IProperty p:
286286
return record.IsPropertyDeclaredByPrimaryConstructor(p);
287287
case IField f:
288-
return true;
288+
return record.PrimaryConstructor != null;
289289
case IEvent e:
290-
return true;
290+
return record.PrimaryConstructor != null;
291291
default:
292292
return false;
293293
}

0 commit comments

Comments
 (0)