Skip to content

Commit de78714

Browse files
Generalize ILInlining special cases for in arguments of ROS<T> ctors.
1 parent ef8d5fc commit de78714

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -337,20 +337,21 @@ static bool IsGeneratedTemporaryForAddressOf(LdLoca loadInst, ILVariable v, ILIn
337337
{
338338
return true;
339339
}
340-
else if (IsPassedToReadOnlySpanOfCharCtor(loadInst))
340+
else if (IsPassedToReadOnlySpanCtor(loadInst))
341341
{
342342
// Always inlining is possible here, because it's an 'in' or 'ref readonly' parameter
343343
// and the C# compiler allows calling it with an rvalue, even though that might produce
344344
// a warning. Note that we don't need to check the expression classification, because
345345
// expressionBuilder.VisitAddressOf will handle creating the copy for us.
346346
// This is necessary, because there are compiler-generated uses of this ctor when
347-
// concatenating a string to a char and our following transforms assume the char is
348-
// already inlined.
347+
// passing a single-element array to a params ROS<T> parameter and our following transforms
348+
// assume the value is already inlined.
349349
return true;
350350
}
351-
if (IsPassedToInlineArrayAsSpan(loadInst))
351+
else if (IsPassedToInlineArrayAsSpan(loadInst))
352352
{
353-
// Inlining is not allowed
353+
// Inlining is not allowed:
354+
// <PrivateImplementationDetails>.InlineArrayAsReadOnlySpan(GetInlineArray()) is invalid C# code
354355
return false;
355356
}
356357
else if (IsPassedToInParameter(loadInst))
@@ -491,13 +492,16 @@ internal static bool IsPassedToInParameter(LdLoca ldloca)
491492
return call.GetParameter(ldloca.ChildIndex)?.ReferenceKind is ReferenceKind.In;
492493
}
493494

494-
static bool IsPassedToReadOnlySpanOfCharCtor(LdLoca ldloca)
495+
static bool IsPassedToReadOnlySpanCtor(LdLoca ldloca)
495496
{
496497
if (ldloca.Parent is not NewObj call)
497498
{
498499
return false;
499500
}
500-
return IsReadOnlySpanCharCtor(call.Method);
501+
var method = call.Method;
502+
return method.IsConstructor
503+
&& method.Parameters.Count == 1
504+
&& method.DeclaringType.IsKnownType(KnownTypeCode.ReadOnlySpanOfT);
501505
}
502506

503507
internal static bool IsReadOnlySpanCharCtor(IMethod method)

0 commit comments

Comments
 (0)