Skip to content

Commit 202c5e2

Browse files
Fix #3383: more aggressively transform object initializers on structs
1 parent fb2561a commit 202c5e2

File tree

3 files changed

+45
-40
lines changed

3 files changed

+45
-40
lines changed

ICSharpCode.Decompiler.Tests/TestCases/Correctness/InitializerTests.cs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -318,14 +318,6 @@ public static void CollectionInitializerInsideObjectInitializers()
318318
};
319319
}
320320

321-
public static void NotAStructInitializer_DefaultConstructor()
322-
{
323-
InitializerTests.StructData data = new InitializerTests.StructData();
324-
data.Field = 1;
325-
data.Property = 2;
326-
InitializerTests.X(InitializerTests.Y(), data);
327-
}
328-
329321
public static void StructInitializer_DefaultConstructor()
330322
{
331323
InitializerTests.X(InitializerTests.Y(), new InitializerTests.StructData {
@@ -334,14 +326,6 @@ public static void StructInitializer_DefaultConstructor()
334326
});
335327
}
336328

337-
public static void NotAStructInitializer_ExplicitConstructor()
338-
{
339-
InitializerTests.StructData data = new InitializerTests.StructData(0);
340-
data.Field = 1;
341-
data.Property = 2;
342-
InitializerTests.X(InitializerTests.Y(), data);
343-
}
344-
345329
public static void StructInitializer_ExplicitConstructor()
346330
{
347331
InitializerTests.X(InitializerTests.Y(), new InitializerTests.StructData(0) {

ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,51 @@ public Issue3392Type(object x)
247247

248248
}
249249
}
250+
251+
private class StructInitPropertiesTest
252+
{
253+
private class TypeA
254+
{
255+
public int A { get; set; }
256+
public int B { get; set; }
257+
}
258+
259+
private struct TypeB
260+
{
261+
public int A { get; set; }
262+
public int B { get; set; }
263+
}
264+
265+
private struct TypeC
266+
{
267+
public int A { get; init; }
268+
public int B { get; init; }
269+
}
270+
271+
private static TypeA TestA()
272+
{
273+
return new TypeA {
274+
A = 1,
275+
B = 2
276+
};
277+
}
278+
279+
private static TypeB TestB()
280+
{
281+
return new TypeB {
282+
A = 1,
283+
B = 2
284+
};
285+
}
286+
287+
private static TypeC TestC()
288+
{
289+
return new TypeC {
290+
A = 1,
291+
B = 2
292+
};
293+
}
294+
}
250295
#endif
251296
#endregion
252297

@@ -928,14 +973,6 @@ public static void CollectionInitializerInsideObjectInitializers()
928973
});
929974
}
930975

931-
public static void NotAStructInitializer_DefaultConstructor()
932-
{
933-
StructData structData = default(StructData);
934-
structData.Field = 1;
935-
structData.Property = 2;
936-
X(Y(), structData);
937-
}
938-
939976
public static void StructInitializer_DefaultConstructor()
940977
{
941978
X(Y(), new StructData {
@@ -956,14 +993,6 @@ public void InliningOfStFldTarget()
956993
};
957994
}
958995

959-
public static void NotAStructInitializer_ExplicitConstructor()
960-
{
961-
StructData structData = new StructData(0);
962-
structData.Field = 1;
963-
structData.Property = 2;
964-
X(Y(), structData);
965-
}
966-
967996
public static void StructInitializer_ExplicitConstructor()
968997
{
969998
X(Y(), new StructData(0) {

ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,6 @@ void IStatementTransform.Run(Block block, int pos, StatementTransformContext con
7373
instType = newObjInst.Method.DeclaringType;
7474
break;
7575
case DefaultValue defaultVal:
76-
if (defaultVal.ILStackWasEmpty && v.Kind == VariableKind.Local && !currentMethod.IsConstructor)
77-
{
78-
// on statement level (no other expressions on IL stack),
79-
// prefer to keep local variables (but not stack slots),
80-
// unless we are in a constructor (where inlining object initializers might be
81-
// critical for the base ctor call)
82-
return;
83-
}
8476
instType = defaultVal.Type;
8577
break;
8678
case Call c when c.Method.FullNameIs("System.Activator", "CreateInstance") && c.Method.TypeArguments.Count == 1:

0 commit comments

Comments
 (0)