Skip to content

Commit b71ff69

Browse files
Add support for InlineArrayConversion
1 parent 7edda6d commit b71ff69

File tree

5 files changed

+56
-4
lines changed

5 files changed

+56
-4
lines changed

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
// #include "../../../ICSharpCode.Decompiler/Util/CSharpPrimitiveCast.cs"
2020

2121
using System;
22+
using System.Runtime.CompilerServices;
2223

2324
using ICSharpCode.Decompiler.Util;
2425

@@ -111,6 +112,9 @@ static void Main(string[] args)
111112

112113
Console.WriteLine(ReadZeroTerminatedString("Hello World!".Length));
113114
C1.Test();
115+
#if ROSLYN2 && !NET40
116+
C3.Run();
117+
#endif
114118
}
115119

116120
static void RunTest(bool checkForOverflow)
@@ -199,4 +203,32 @@ public static implicit operator C1(C2 c)
199203
return new C1();
200204
}
201205
}
206+
207+
#if ROSLYN2 && !NET40
208+
class C3
209+
{
210+
[InlineArray(4)] struct MyArray { private int elem; }
211+
212+
static void Foo(object o)
213+
{
214+
Console.WriteLine("Foo(object) called");
215+
}
216+
217+
static void Foo(ReadOnlySpan<int> o)
218+
{
219+
Console.WriteLine("Foo(ReadOnlySpan<int>) called");
220+
}
221+
222+
static void Test(MyArray arr)
223+
{
224+
Foo((object)arr);
225+
}
226+
227+
public static void Run()
228+
{
229+
Console.WriteLine("C3.Run() called");
230+
Test(default);
231+
}
232+
}
233+
#endif
202234
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ public void OverloadResolution()
6060
Byte16 buffer2 = GetByte16();
6161
Receiver((ReadOnlySpan<byte>)buffer2);
6262
Byte16 buffer3 = GetByte16();
63-
ReceiverSpan((Span<byte>)buffer3);
63+
ReceiverSpan(buffer3);
6464
Byte16 buffer4 = GetByte16();
65-
ReceiverReadOnlySpan((ReadOnlySpan<byte>)buffer4);
65+
ReceiverReadOnlySpan(buffer4);
6666
}
6767

6868
public Byte16 GetByte16()

ICSharpCode.Decompiler/CSharp/Resolver/CSharpConversions.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,12 +230,17 @@ Conversion StandardImplicitConversion(IType fromType, IType toType, bool allowTu
230230
if (c != Conversion.None)
231231
return c;
232232
}
233+
if ((toType.IsKnownType(KnownTypeCode.SpanOfT) || toType.IsKnownType(KnownTypeCode.ReadOnlySpanOfT))
234+
&& fromType.IsInlineArrayType())
235+
{
236+
return Conversion.InlineArrayConversion;
237+
}
233238
return Conversion.None;
234239
}
235240

236241
/// <summary>
237242
/// Gets whether the type 'fromType' is convertible to 'toType'
238-
/// using one of the conversions allowed when satisying constraints (§4.4.4)
243+
/// using one of the conversions allowed when satisfying constraints (§4.4.4)
239244
/// </summary>
240245
public bool IsConstraintConvertible(IType fromType, IType toType)
241246
{

ICSharpCode.Decompiler/TypeSystem/Implementation/KnownAttributes.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,14 @@ public enum KnownAttribute
112112

113113
// C# 11 attributes:
114114
RequiredAttribute,
115+
116+
// C# 12 attributes:
117+
InlineArray,
115118
}
116119

117120
public static class KnownAttributes
118121
{
119-
internal const int Count = (int)KnownAttribute.RequiredAttribute + 1;
122+
internal const int Count = (int)KnownAttribute.InlineArray + 1;
120123

121124
static readonly TopLevelTypeName[] typeNames = new TopLevelTypeName[Count]{
122125
default,
@@ -186,6 +189,8 @@ public static class KnownAttributes
186189
new TopLevelTypeName("System.Runtime.CompilerServices", "PreserveBaseOverridesAttribute"),
187190
// C# 11 attributes:
188191
new TopLevelTypeName("System.Runtime.CompilerServices", "RequiredMemberAttribute"),
192+
// C# 12 attributes:
193+
new TopLevelTypeName("System.Runtime.CompilerServices", "InlineArrayAttribute"),
189194
};
190195

191196
public static ref readonly TopLevelTypeName GetTypeName(this KnownAttribute attr)

ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,16 @@ bool IsUnmanagedTypeInternal(IType type)
306306
}
307307
}
308308

309+
public static bool IsInlineArrayType(this IType type)
310+
{
311+
if (type.Kind != TypeKind.Struct)
312+
return false;
313+
var td = type.GetDefinition();
314+
if (td == null)
315+
return false;
316+
return td.HasAttribute(KnownAttribute.InlineArray);
317+
}
318+
309319
/// <summary>
310320
/// Gets whether the type is the specified known type.
311321
/// For generic known types, this returns true for any parameterization of the type (and also for the definition itself).

0 commit comments

Comments
 (0)