Add xfailed pretty test for C# 13 params collections call sites

The fixture is the desired output for params-collection call sites the
decompiler does not reconstruct yet, Assert.Ignore'd pending #829. All
four Roslyn 4.14/latest debug/opt configs compile the fixture and fail
only at the output comparison. Defects the fixture pins down:

- params ReadOnlySpan<T> call sites with non-constant or string
  elements leak the synthesized inline-array structs (declared with
  unspeakable escaped names like _003C_003Ey__InlineArray2<T>), and an
  empty span call prints default(ReadOnlySpan<int>); affects method,
  constructor, and indexer call sites alike.
- params IEnumerable<T>/IReadOnlyList<T> call sites (including
  delegate invocations) leak the compiler-synthesized
  <>z__ReadOnlyArray/<>z__ReadOnlySingleElementList wrapper classes.
- params List<T>/IList<T>/ICollection<T> call sites keep the raw
  CollectionsMarshal.SetCount/AsSpan lowering; params ImmutableArray<T>
  keeps ImmutableCollectionsMarshal.AsImmutableArray.
- params arguments are never collapsed in attribute arguments.
- local-function call sites get no params folding, and the params
  modifier is dropped from local-function declarations (a span
  parameter prints as scoped ReadOnlySpan<T> instead).
- natural-typed lambdas with params parameters print unspeakable
  <>f__AnonymousDelegate types and lose the params modifier.

Assisted-by: Claude:claude-fable-5:Claude Code
This commit is contained in:
Siegfried Pammer
2026-07-29 07:19:21 +02:00
parent 5dbe67d591
commit b374d01003
3 changed files with 122 additions and 0 deletions
@@ -433,6 +433,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
"mscorlib.dll",
"System.dll",
"System.Collections.dll",
"System.Collections.Immutable.dll",
"System.Console.dll",
"System.Core.dll",
"System.Linq.dll",
@@ -788,6 +788,13 @@ namespace ICSharpCode.Decompiler.Tests
await RunForLibrary(cscOptions: cscOptions);
}
[Test]
public async Task ParamsCollectionsCallSites([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)
{
Assert.Ignore("Params collections call sites are not yet reconstructed by the decompiler. See https://github.com/icsharpcode/ILSpy/issues/829");
await RunForLibrary(cscOptions: cscOptions);
}
[Test]
public async Task RefStructInterfaces([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)
{
@@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
public class ParamsCollectionsCallSites
{
public delegate void ParamsEnumerableDelegate(params IEnumerable<int> values);
public class ParamsAttribute : Attribute
{
public ParamsAttribute(params int[] values)
{
}
}
public int this[params ReadOnlySpan<int> values] => values.Length;
public ParamsCollectionsCallSites(params ReadOnlySpan<string> values)
{
}
public static void ParamsEnumerable(params IEnumerable<int> values)
{
}
public static void ParamsGenericEnumerable<T>(params IEnumerable<T> values)
{
}
public static void ParamsGenericSpan<T>(params ReadOnlySpan<T> values)
{
}
public static void ParamsICollection(params ICollection<int> values)
{
}
public static void ParamsIList(params IList<int> values)
{
}
public static void ParamsIReadOnlyList(params IReadOnlyList<int> values)
{
}
public static void ParamsImmutableArray(params ImmutableArray<int> values)
{
}
public static void ParamsList(params List<int> values)
{
}
public static void ParamsReadOnlySpan(params ReadOnlySpan<int> values)
{
}
public static void ParamsSpanOfString(params ReadOnlySpan<string> values)
{
}
public static void SpanCallSites(int x)
{
ParamsReadOnlySpan();
ParamsReadOnlySpan(x);
ParamsReadOnlySpan(x, x + 1);
ParamsSpanOfString("a", "b");
ParamsGenericSpan("a", "b");
}
public static void EnumerableCallSites(int x)
{
ParamsEnumerable(1);
ParamsEnumerable(1, 2, 3);
ParamsEnumerable(x, x + 1);
ParamsIReadOnlyList(1, 2);
ParamsGenericEnumerable(1.0, 2.0);
}
public static void ListCallSites(int x)
{
ParamsList();
ParamsList(1, 2, 3);
ParamsIList(1, 2);
ParamsICollection(x);
}
public static void ImmutableArrayCallSites(int x)
{
ParamsImmutableArray();
ParamsImmutableArray(1, 2, 3);
ParamsImmutableArray(x, x + 1);
}
public static int MemberCallSites(int x)
{
return new ParamsCollectionsCallSites("a", "b")[1, 2, x];
}
public static void DelegateCallSites(ParamsEnumerableDelegate d)
{
d(4, 5);
}
[Params(1, 2, 3)]
public static void AttributeCallSite()
{
}
public static void LocalFunctionCallSites()
{
LocalArray();
LocalArray(1, 2, 3);
LocalSpan(1, 2);
static void LocalArray(params int[] values)
{
}
static void LocalSpan(params ReadOnlySpan<int> values)
{
}
}
public static int NaturalTypeLambdas()
{
var f = (params ReadOnlySpan<int> xs) => xs.Length;
var g = (params IEnumerable<int> xs) => 0;
return f(1, 2) + g(3);
}
}
}