Split out of #4057, which fixes the case where params and parameter default values were printed
on syntax that cannot carry them. Below C# 12 they are now dropped instead, and this issue tracks
that remaining loss.
What happens
public delegate int ParamsDel(params int[] values);
public delegate int OptDel(int x = 42);
public static ParamsDel MakeParams(int seed) => (params int[] values) => values.Length + seed;
public static OptDel MakeOpt(int seed) => (int x = 42) => x + seed;
Decompiled with --languageversion CSharp11_0:
public static ParamsDel MakeParams(int seed)
{
return (int[] values) => values.Length + seed;
}
public static OptDel MakeOpt(int seed)
{
return (int x) => x + seed;
}
Both modifiers are gone. The output still compiles and still binds the way the input did - the
delegate type declares params and the default, and that is what call sites bind against - so
this is a fidelity loss, not a correctness bug. A reader of the C# 11 output cannot tell the
parameter was params or had a default.
The obvious fix only works for one of the two
C# 10 allows attributes on lambda parameters, so the natural repair is to downgrade the modifiers
to the attributes the compiler would have emitted anyway.
That works for the default value. Verified compiling at LangVersion 11:
return ([Optional][DefaultParameterValue(5)] int x) => x * 2;
It does not work for params:
return ([ParamArray] int[] xs) => xs.Length;
// error CS0674: Do not use 'System.ParamArrayAttribute'/
// 'System.Runtime.CompilerServices.ParamCollectionAttribute'. Use the 'params' keyword instead.
CS0674 rejects [ParamArray] on any parameter, and anonymous methods cannot declare params
either (CS1670), so below C# 12 there is no legal way to spell it on the anonymous function at
all. Dropping it may simply be the correct answer for that half.
Worth knowing: the closed #4004 branch (natural-type-lambdas-methods) carries a commit
"Downgrade params and default values to attributes on pre-C# 12 lambdas" which emits exactly the
[ParamArray] form above, with an Ugly test pinning it. That output does not compile, so the
commit should not be lifted as-is if this is picked up.
Suggested scope
- Emit
[Optional]/[DefaultParameterValue] for a default value below C# 12.
- Leave
params dropped, and pin that with a test so the CS0674 form cannot come back.
Written by an AI agent (Claude) on Siegfried's behalf.
Split out of #4057, which fixes the case where
paramsand parameter default values were printedon syntax that cannot carry them. Below C# 12 they are now dropped instead, and this issue tracks
that remaining loss.
What happens
Decompiled with
--languageversion CSharp11_0:Both modifiers are gone. The output still compiles and still binds the way the input did - the
delegate type declares
paramsand the default, and that is what call sites bind against - sothis is a fidelity loss, not a correctness bug. A reader of the C# 11 output cannot tell the
parameter was
paramsor had a default.The obvious fix only works for one of the two
C# 10 allows attributes on lambda parameters, so the natural repair is to downgrade the modifiers
to the attributes the compiler would have emitted anyway.
That works for the default value. Verified compiling at
LangVersion 11:It does not work for
params:CS0674 rejects
[ParamArray]on any parameter, and anonymous methods cannot declareparamseither (CS1670), so below C# 12 there is no legal way to spell it on the anonymous function at
all. Dropping it may simply be the correct answer for that half.
Worth knowing: the closed #4004 branch (
natural-type-lambdas-methods) carries a commit"Downgrade params and default values to attributes on pre-C# 12 lambdas" which emits exactly the
[ParamArray]form above, with an Ugly test pinning it. That output does not compile, so thecommit should not be lifted as-is if this is picked up.
Suggested scope
[Optional]/[DefaultParameterValue]for a default value below C# 12.paramsdropped, and pin that with a test so the CS0674 form cannot come back.Written by an AI agent (Claude) on Siegfried's behalf.