From a8cbbce2998bbb8bc04213a3890b6903b8d66a21 Mon Sep 17 00:00:00 2001
From: Charles Stoner <10732005+cston@users.noreply.github.com>
Date: Wed, 2 Apr 2025 15:51:48 -0700
Subject: [PATCH 01/14] Correct DefaultParameterValueAttribute in diagnostic
---
src/Compilers/CSharp/Portable/CSharpResources.resx | 2 +-
.../Symbols/Source/SourceComplexParameterSymbol.cs | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.cs.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.de.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.es.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.fr.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.it.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.ja.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.ko.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.pl.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.pt-BR.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.ru.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.tr.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf | 4 ++--
.../CSharp/Test/Emit/Emit/OptionalArgumentsTests.cs | 10 +++++-----
.../CSharp/Test/Emit3/RefReadonlyParameterTests.cs | 10 +++++-----
.../CSharp/Test/Emit3/Semantics/ExtensionTests.cs | 2 +-
.../Test/Semantic/Semantics/NamedAndOptionalTests.cs | 4 ++--
.../Semantic/Semantics/NullableReferenceTypesTests.cs | 4 ++--
.../CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs | 2 +-
21 files changed, 45 insertions(+), 45 deletions(-)
diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index 611416fe327f8..7fd9b1384ea79 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -4062,7 +4062,7 @@ You should consider suppressing the warning only if you're sure that you don't w
Named argument '{0}' is used out-of-position but is followed by an unnamed argument
- Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
Default parameter value for '{0}' must be a compile-time constant
diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceComplexParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceComplexParameterSymbol.cs
index 6bbab27a68ff2..b0b2e52c96303 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceComplexParameterSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceComplexParameterSymbol.cs
@@ -756,7 +756,7 @@ protected override void DecodeWellKnownAttributeImpl(ref DecodeWellKnownAttribut
if (HasDefaultArgumentSyntax)
{
- // error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
diagnostics.Add(ErrorCode.ERR_DefaultValueUsedWithAttributes, arguments.AttributeSyntaxOpt.Name.Location);
}
}
@@ -952,7 +952,7 @@ private ConstantValue DecodeDefaultParameterValueAttribute(CSharpAttributeData a
if (HasDefaultArgumentSyntax)
{
- // error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
if (diagnose)
{
diagnosticsOpt.Add(ErrorCode.ERR_DefaultValueUsedWithAttributes, node.Name.Location);
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
index 344d4b128b789..41fd691d27954 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
@@ -11327,8 +11327,8 @@ Potlačení upozornění zvažte jenom v případě, když určitě nechcete če
- Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
- Nejde zadat výchozí hodnotu parametru v kombinaci s atributy DefaultParameterAttribute nebo OptionalAttribute.
+ Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ Nejde zadat výchozí hodnotu parametru v kombinaci s atributy DefaultParameterAttribute nebo OptionalAttribute.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
index d8cc687591ed3..301229db797c5 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
@@ -11327,8 +11327,8 @@ Sie sollten das Unterdrücken der Warnung nur in Betracht ziehen, wenn Sie siche
- Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
- Es kann kein Standardparameterwert in Verbindung mit "DefaultParameterAttribute" oder "OptionalAttribute" angegeben werden.
+ Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ Es kann kein Standardparameterwert in Verbindung mit "DefaultParameterAttribute" oder "OptionalAttribute" angegeben werden.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
index 1bbebe82943bb..83575dbefe3a2 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
@@ -11327,8 +11327,8 @@ Considere la posibilidad de suprimir la advertencia solo si tiene la seguridad d
- Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
- No se puede especificar un valor de parámetro predeterminado junto con DefaultParameterAttribute u OptionalAttribute
+ Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ No se puede especificar un valor de parámetro predeterminado junto con DefaultParameterAttribute u OptionalAttribute
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
index cafe17844a0b4..a80bcf844e55d 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
@@ -11327,8 +11327,8 @@ Supprimez l'avertissement seulement si vous êtes sûr de ne pas vouloir attendr
- Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
- Impossible de spécifier une valeur de paramètre par défaut conjointement à DefaultParameterAttribute ou OptionalAttribute
+ Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ Impossible de spécifier une valeur de paramètre par défaut conjointement à DefaultParameterAttribute ou OptionalAttribute
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
index db97ace0ae56d..134add8f363ab 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
@@ -11327,8 +11327,8 @@ Come procedura consigliata, è consigliabile attendere sempre la chiamata.
- Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
- Impossibile specificare un valore di parametro predefinito insieme a DefaultParameterAttribute o OptionalAttribute
+ Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ Impossibile specificare un valore di parametro predefinito insieme a DefaultParameterAttribute o OptionalAttribute
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
index a1ba411fc0134..e50469348d849 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
@@ -11327,8 +11327,8 @@ You should consider suppressing the warning only if you're sure that you don't w
- Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
- DefaultParameterAttribute または OptionalAttribute と共に既定パラメーター値を指定することはできません
+ Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ DefaultParameterAttribute または OptionalAttribute と共に既定パラメーター値を指定することはできません
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
index dea7078e009e4..43c44b02c76e2 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
@@ -11327,8 +11327,8 @@ You should consider suppressing the warning only if you're sure that you don't w
- Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
- DefaultParameterAttribute 또는 OptionalAttribute와 함께 기본 매개 변수 값을 지정할 수 없습니다.
+ Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ DefaultParameterAttribute 또는 OptionalAttribute와 함께 기본 매개 변수 값을 지정할 수 없습니다.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
index 434cd933d2262..b3decad616b05 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
@@ -11327,8 +11327,8 @@ Pominięcie ostrzeżenia należy wziąć pod uwagę tylko w sytuacji, gdy na pew
- Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
- Nie można określić wartości domyślnej parametru w połączeniu z klasami DefaultParameterAttribute lub OptionalAttribute
+ Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ Nie można określić wartości domyślnej parametru w połączeniu z klasami DefaultParameterAttribute lub OptionalAttribute
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
index 7c7e74a0eb44b..a85e5effa2662 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
@@ -11327,8 +11327,8 @@ Você pode suprimir o aviso se tiver certeza de que não vai querer aguardar a c
- Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
- Não é possível especificar um valor de parâmetro padrão junto com DefaultParameterAttribute ou OptionalAttribute
+ Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ Não é possível especificar um valor de parâmetro padrão junto com DefaultParameterAttribute ou OptionalAttribute
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
index 96459e55e0274..55919fd6242c5 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
@@ -11328,8 +11328,8 @@ You should consider suppressing the warning only if you're sure that you don't w
- Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
- Не удалось указать значение параметра по умолчанию вместе с DefaultParameterAttribute или OptionalAttribute.
+ Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ Не удалось указать значение параметра по умолчанию вместе с DefaultParameterAttribute или OptionalAttribute.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
index 85efa757102a7..9bd8e69dbf874 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
@@ -11327,8 +11327,8 @@ Yalnızca asenkron çağrının tamamlanmasını beklemek istemediğinizden ve
- Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
- DefaultParameterAttribute veya OptionalAttribute ile birlikte varsayılan parametre değeri belirtilemez
+ Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ DefaultParameterAttribute veya OptionalAttribute ile birlikte varsayılan parametre değeri belirtilemez
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
index d05cbeb6be7e7..9170d809cbcb0 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
@@ -11327,8 +11327,8 @@ You should consider suppressing the warning only if you're sure that you don't w
- Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
- 不能同时指定默认参数值与 DefaultParameterAttribute 或 OptionalAttribute
+ Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ 不能同时指定默认参数值与 DefaultParameterAttribute 或 OptionalAttribute
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
index b30ef2cfe42ab..1e6772bc6a43b 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
@@ -11327,8 +11327,8 @@ You should consider suppressing the warning only if you're sure that you don't w
- Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
- 不能連同 DefaultParameterAttribute 或 OptionalAttribute 一起指定預設參數值
+ Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ 不能連同 DefaultParameterAttribute 或 OptionalAttribute 一起指定預設參數值
diff --git a/src/Compilers/CSharp/Test/Emit/Emit/OptionalArgumentsTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/OptionalArgumentsTests.cs
index cc001016cb53b..876153b624004 100644
--- a/src/Compilers/CSharp/Test/Emit/Emit/OptionalArgumentsTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/Emit/OptionalArgumentsTests.cs
@@ -255,10 +255,10 @@ interface I
delegate void D([DecimalConstant(0, 0, 0, 0, 3)]decimal b = 4);
";
CreateCompilation(source).VerifyDiagnostics(
- // (5,14): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // (5,14): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
// void F1([DefaultParameterValue(1)]int o = 2);
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(5, 14),
- // (6,14): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // (6,14): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
// void F2([DefaultParameterValue(1)]decimal o = 2);
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(6, 14),
// (6,51): error CS8017: The parameter has multiple distinct default values.
@@ -267,7 +267,7 @@ interface I
// (7,57): error CS8017: The parameter has multiple distinct default values.
// void F4([DecimalConstant(0, 0, 0, 0, 1)]decimal o = 2);
Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "2").WithLocation(7, 57),
- // (8,35): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // (8,35): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
// void F6([DateTimeConstant(1), DefaultParameterValue(1), DecimalConstant(0, 0, 0, 0, 1)]int o = 1);
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(8, 35),
// (8,61): error CS8017: The parameter has multiple distinct default values.
@@ -279,13 +279,13 @@ interface I
// (9,35): error CS8017: The parameter has multiple distinct default values.
// void F7([DateTimeConstant(2), DecimalConstant(0, 0, 0, 0, 2), DefaultParameterValue(2)]decimal o = 2);
Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "DecimalConstant(0, 0, 0, 0, 2)").WithLocation(9, 35),
- // (9,67): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // (9,67): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
// void F7([DateTimeConstant(2), DecimalConstant(0, 0, 0, 0, 2), DefaultParameterValue(2)]decimal o = 2);
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(9, 67),
// (9,104): error CS8017: The parameter has multiple distinct default values.
// void F7([DateTimeConstant(2), DecimalConstant(0, 0, 0, 0, 2), DefaultParameterValue(2)]decimal o = 2);
Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "2").WithLocation(9, 104),
- // (10,25): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // (10,25): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
// object this[int a, [DefaultParameterValue(1)]int o = 2] { get; set; }
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(10, 25),
// (10,58): error CS8017: The parameter has multiple distinct default values.
diff --git a/src/Compilers/CSharp/Test/Emit3/RefReadonlyParameterTests.cs b/src/Compilers/CSharp/Test/Emit3/RefReadonlyParameterTests.cs
index 12482bd5997b1..7359081866010 100644
--- a/src/Compilers/CSharp/Test/Emit3/RefReadonlyParameterTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/RefReadonlyParameterTests.cs
@@ -4621,7 +4621,7 @@ class C
}
""";
CreateCompilation(source).VerifyDiagnostics(
- // (4,20): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // (4,20): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
// static void M([DefaultParameterValue(1)] ref readonly int i = 1) => throw null;
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(4, 20),
// (4,67): warning CS9200: A default value is specified for 'ref readonly' parameter 'i', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
@@ -4643,7 +4643,7 @@ class C
}
""";
CreateCompilation(source).VerifyDiagnostics(
- // (4,20): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // (4,20): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
// static void M([Optional] ref readonly int i = 1) => throw null;
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "Optional").WithLocation(4, 20),
// (4,51): warning CS9200: A default value is specified for 'ref readonly' parameter 'i', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
@@ -4662,10 +4662,10 @@ class C
}
""";
CreateCompilation(source).VerifyDiagnostics(
- // (4,20): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // (4,20): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
// static void M([Optional, DefaultParameterValue(1)] ref readonly int i = 1) => throw null;
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "Optional").WithLocation(4, 20),
- // (4,30): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // (4,30): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
// static void M([Optional, DefaultParameterValue(1)] ref readonly int i = 1) => throw null;
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(4, 30),
// (4,77): warning CS9200: A default value is specified for 'ref readonly' parameter 'i', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
@@ -4797,7 +4797,7 @@ static void Main()
}
""";
CreateCompilation(source).VerifyDiagnostics(
- // (6,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // (6,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
// static void M2([Optional, DecimalConstant(1, 0, 0u, 0u, 11u)] ref readonly decimal d = 1.1m) => throw null;
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "Optional").WithLocation(6, 21),
// (6,92): warning CS9200: A default value is specified for 'ref readonly' parameter 'd', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs
index 49b55402cfecc..bebbfffb467bc 100644
--- a/src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs
@@ -2497,7 +2497,7 @@ public static class Extensions
// (3,15): error CS9284: The receiver parameter of an extension cannot have a default value
// extension([System.Runtime.InteropServices.DefaultParameterValue(1)] int o = 2) { }
Diagnostic(ErrorCode.ERR_ExtensionParameterDisallowsDefaultValue, "[System.Runtime.InteropServices.DefaultParameterValue(1)] int o = 2").WithLocation(3, 15),
- // (3,16): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // (3,16): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
// extension([System.Runtime.InteropServices.DefaultParameterValue(1)] int o = 2) { }
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "System.Runtime.InteropServices.DefaultParameterValue").WithLocation(3, 16));
}
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NamedAndOptionalTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NamedAndOptionalTests.cs
index 10ebc0f4cb410..ce2f5d8141272 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/NamedAndOptionalTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NamedAndOptionalTests.cs
@@ -962,13 +962,13 @@ public static int Main(){
}
";
CreateCompilation(source).VerifyDiagnostics(
- // (9,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // (9,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
// public int Bar([DefaultParameterValue(1)]int i = 2) {
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(9, 21),
// (9,54): error CS8017: The parameter has multiple distinct default values.
// public int Bar([DefaultParameterValue(1)]int i = 2) {
Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "2").WithLocation(9, 54),
- // (5,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // (5,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
// public int Goo([Optional]object i = null) {
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "Optional").WithLocation(5, 21)
);
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
index 7315a2e033e0d..cccbae0f0badc 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
@@ -82159,10 +82159,10 @@ public void M3([Optional, DefaultParameterValue(null)] object obj = null)
// (9,31): error CS8017: The parameter has multiple distinct default values.
// public void M2([Optional, DefaultParameterValue(default)] object obj)
Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "DefaultParameterValue(default)").WithLocation(9, 31),
- // (13,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // (13,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
// public void M3([Optional, DefaultParameterValue(null)] object obj = null)
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "Optional").WithLocation(13, 21),
- // (13,31): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // (13,31): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
// public void M3([Optional, DefaultParameterValue(null)] object obj = null)
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(13, 31),
// (13,73): warning CS8625: Cannot convert null literal to non-nullable reference type.
diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs
index 35eeaa428bee8..7780a6bdfe315 100644
--- a/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs
+++ b/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs
@@ -16148,7 +16148,7 @@ public static void Main() { }
}
";
CreateCompilation(text).VerifyDiagnostics(
- // (5,22): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ // (5,22): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
// public void goo([OptionalAttribute]int p = 1)
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "OptionalAttribute")
);
From 51406f917334187a237630b40a4b090a70dc9f8e Mon Sep 17 00:00:00 2001
From: Charles Stoner <10732005+cston@users.noreply.github.com>
Date: Wed, 5 Mar 2025 14:00:56 -0800
Subject: [PATCH 02/14] Expression trees: optional arguments
---
.../CSharp/Portable/Errors/MessageID.cs | 2 +
.../DiagnosticsPass_ExpressionTrees.cs | 2 +-
...xpressionOptionalAndNamedArgumentsTests.cs | 749 ++++++++++++++++++
3 files changed, 752 insertions(+), 1 deletion(-)
create mode 100644 src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
diff --git a/src/Compilers/CSharp/Portable/Errors/MessageID.cs b/src/Compilers/CSharp/Portable/Errors/MessageID.cs
index f2a30c73742ed..cd06dbeed0fa1 100644
--- a/src/Compilers/CSharp/Portable/Errors/MessageID.cs
+++ b/src/Compilers/CSharp/Portable/Errors/MessageID.cs
@@ -301,6 +301,7 @@ internal enum MessageID
IDS_FeaturePartialEventsAndConstructors = MessageBase + 12852,
IDS_FeatureExtensions = MessageBase + 12853,
IDS_FeatureNullConditionalAssignment = MessageBase + 12854,
+ IDS_FeatureExpressionOptionalAndNamedArguments = MessageBase + 12855,
}
// Message IDs may refer to strings that need to be localized.
@@ -488,6 +489,7 @@ internal static LanguageVersion RequiredVersion(this MessageID feature)
case MessageID.IDS_FeaturePartialEventsAndConstructors:
case MessageID.IDS_FeatureExtensions:
case MessageID.IDS_FeatureNullConditionalAssignment:
+ case MessageID.IDS_FeatureExpressionOptionalAndNamedArguments:
return LanguageVersion.Preview;
// C# 13.0 features.
diff --git a/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs b/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs
index 947a42ec2fe1f..afa06a0786fd9 100644
--- a/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs
@@ -328,7 +328,7 @@ private void VisitCall(
{
Error(ErrorCode.ERR_ExpressionTreeContainsIndexedProperty, node);
}
- else if (hasDefaultArgument(arguments, defaultArguments))
+ else if (hasDefaultArgument(arguments, defaultArguments) && !_compilation.IsFeatureEnabled(MessageID.IDS_FeatureExpressionOptionalAndNamedArguments))
{
Error(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, node);
}
diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
new file mode 100644
index 0000000000000..613c71cd4e687
--- /dev/null
+++ b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
@@ -0,0 +1,749 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
+using Xunit;
+
+namespace Microsoft.CodeAnalysis.CSharp.UnitTests
+{
+ public class ExpressionOptionalAndNamedArgumentsTests : CSharpTestBase
+ {
+ // PROTOTYPE: Named arguments: Test overloads where the args are in order for one, but not the other.
+ // PROTOTYPE: Document breaking changes. Are additional overloads now considered (at least those with default parameters)? Test those cases with language version.
+
+ [Theory]
+ [CombinatorialData]
+ public void OptionalParameter_01(
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ bool useIn,
+ bool useCompilationReference)
+ {
+ string refKind = useIn ? "in" : "";
+ string sourceA = $$"""
+ public static class A
+ {
+ public static T GetValue({{refKind}} T t = default) => t;
+ }
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = AsReference(comp, useCompilationReference);
+
+ string sourceB = $$"""
+ using System;
+ using System.Linq.Expressions;
+ struct S
+ {
+ }
+ class Program
+ {
+ static void Main()
+ {
+ Report(A.GetValue());
+ Report(A.GetValue());
+ Report(A.GetValue());
+ Report(Run(() => A.GetValue()));
+ Report(Run(() => A.GetValue()));
+ Report(Run(() => A.GetValue()));
+ }
+ static void Report(object arg)
+ {
+ Console.WriteLine(arg is null ? "null" : arg.ToString());
+ }
+ static T Run(Expression> e)
+ {
+ var f = e.Compile();
+ return f();
+ }
+ }
+ """;
+ comp = CreateCompilation(
+ sourceB,
+ references: [refA],
+ parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
+ options: TestOptions.ReleaseExe);
+ if (languageVersion == LanguageVersion.CSharp13)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (13,26): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Report(Run(() => A.GetValue()));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetValue()").WithLocation(13, 26),
+ // (14,26): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Report(Run(() => A.GetValue()));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetValue()").WithLocation(14, 26),
+ // (15,26): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Report(Run(() => A.GetValue()));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetValue()").WithLocation(15, 26));
+ }
+ else
+ {
+ var verifier = CompileAndVerify(
+ comp,
+ expectedOutput: """
+ 0
+ null
+ S
+ 0
+ null
+ S
+ """);
+ verifier.VerifyDiagnostics();
+ }
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void OptionalParameter_02(bool useIn, bool preferInterpretation, bool useCompilationReference)
+ {
+ string value = preferInterpretation ? "true" : "false";
+ string refKind = useIn ? "in" : "";
+ string sourceA = $$"""
+ public static class A
+ {
+ public static int GetIntValue({{refKind}} int i = 10) => i;
+ public static string GetStringValue({{refKind}} string s = "default") => s;
+ public static object GetObjectValue({{refKind}} object o = null) => o;
+ }
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = AsReference(comp, useCompilationReference);
+
+ string sourceB = $$"""
+ using System;
+ using System.Linq.Expressions;
+ class Program
+ {
+ static void Main()
+ {
+ Report(A.GetIntValue());
+ Report(A.GetStringValue());
+ Report(A.GetObjectValue());
+ Report(Run(() => A.GetIntValue()));
+ Report(Run(() => A.GetStringValue()));
+ Report(Run(() => A.GetObjectValue()));
+ }
+ static void Report(object arg)
+ {
+ Console.WriteLine(arg is null ? "null" : arg.ToString());
+ }
+ static T Run(Expression> e)
+ {
+ var f = e.Compile(preferInterpretation: {{value}});
+ return f();
+ }
+ }
+ """;
+ var verifier = CompileAndVerify(
+ sourceB,
+ references: [refA],
+ expectedOutput: """
+ 10
+ default
+ null
+ 10
+ default
+ null
+ """);
+ verifier.VerifyDiagnostics();
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void OptionalParameter_AndParams(bool useIn, bool preferInterpretation, bool useCompilationReference)
+ {
+ string value = preferInterpretation ? "true" : "false";
+ string refKind = useIn ? "in" : "";
+ string sourceA = $$"""
+ public static class A
+ {
+ public static T GetValue({{refKind}} T x, {{refKind}} T y = default, params T[] args) => y;
+ }
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = AsReference(comp, useCompilationReference);
+
+ string sourceB = $$"""
+ using System;
+ using System.Linq.Expressions;
+ struct S
+ {
+ }
+ class Program
+ {
+ static void Main()
+ {
+ Report(A.GetValue(1));
+ Report(A.GetValue(2, 3, 4));
+ Report(Run(() => A.GetValue(1)));
+ Report(Run(() => A.GetValue(2, 3, 4)));
+ }
+ static void Report(object arg)
+ {
+ Console.WriteLine(arg is null ? "null" : arg.ToString());
+ }
+ static T Run(Expression> e)
+ {
+ var f = e.Compile(preferInterpretation: {{value}});
+ return f();
+ }
+ }
+ """;
+ var verifier = CompileAndVerify(
+ sourceB,
+ references: [refA],
+ expectedOutput: """
+ 0
+ 3
+ 0
+ 3
+ """);
+ verifier.VerifyDiagnostics();
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void OptionalParameter_Constructor(
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ bool useCompilationReference)
+ {
+ string sourceA = $$"""
+ public class A
+ {
+ public readonly string X;
+ public readonly int Y;
+ public A(string x = "default", in int y = 10) { X = x; Y = y; }
+ }
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = AsReference(comp, useCompilationReference);
+
+ string sourceB = $$"""
+ using System;
+ using System.Linq.Expressions;
+ class Program
+ {
+ static void Main()
+ {
+ Report(new A("str"));
+ Report(new A());
+ Report(Run(() => new A("str")));
+ Report(Run(() => new A()));
+ }
+ static void Report(A a)
+ {
+ Console.WriteLine((a.X, a.Y));
+ }
+ static T Run(Expression> e)
+ {
+ var f = e.Compile();
+ return f();
+ }
+ }
+ """;
+ comp = CreateCompilation(
+ sourceB,
+ references: [refA],
+ parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
+ options: TestOptions.ReleaseExe);
+ if (languageVersion == LanguageVersion.CSharp13)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (9,26): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Report(Run(() => new A("str")));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, @"new A(""str"")").WithLocation(9, 26),
+ // (10,26): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Report(Run(() => new A()));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "new A()").WithLocation(10, 26));
+ }
+ else
+ {
+ var verifier = CompileAndVerify(
+ comp,
+ expectedOutput: """
+ (str, 10)
+ (default, 10)
+ (str, 10)
+ (default, 10)
+ """);
+ verifier.VerifyDiagnostics();
+ }
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void OptionalParameter_Indexer(
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ bool useCompilationReference)
+ {
+ string sourceA = $$"""
+ public class A
+ {
+ public int this[int x, int y = 10] => y;
+ }
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = AsReference(comp, useCompilationReference);
+
+ string sourceB = $$"""
+ using System;
+ using System.Linq.Expressions;
+ class Program
+ {
+ static void Main()
+ {
+ var a = new A();
+ Console.WriteLine(a[1, 2]);
+ Console.WriteLine(a[3]);
+ Console.WriteLine(Run(() => a[1, 2]));
+ Console.WriteLine(Run(() => a[3]));
+ }
+ static T Run(Expression> e)
+ {
+ var f = e.Compile();
+ return f();
+ }
+ }
+ """;
+ comp = CreateCompilation(
+ sourceB,
+ references: [refA],
+ parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
+ options: TestOptions.ReleaseExe);
+ if (languageVersion == LanguageVersion.CSharp13)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (11,37): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Console.WriteLine(Run(() => a[3]));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "a[3]").WithLocation(11, 37));
+ }
+ else
+ {
+ var verifier = CompileAndVerify(
+ comp,
+ expectedOutput: """
+ 2
+ 10
+ 2
+ 10
+ """);
+ verifier.VerifyDiagnostics();
+ }
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void OptionalParameter_Delegate(
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ bool useCompilationReference)
+ {
+ string sourceA = $$"""
+ public delegate int D(int x, in int y = 10);
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = AsReference(comp, useCompilationReference);
+
+ string sourceB = $$"""
+ using System;
+ using System.Linq.Expressions;
+ class Program
+ {
+ static void Main()
+ {
+ D d = F;
+ Console.WriteLine(d(1, 2));
+ Console.WriteLine(d(3));
+ Console.WriteLine(Run(() => d(1, 2)));
+ Console.WriteLine(Run(() => d(3)));
+ }
+ static T Run(Expression> e)
+ {
+ var f = e.Compile();
+ return f();
+ }
+ static T F(T x, in T y) => y;
+ }
+ """;
+ comp = CreateCompilation(
+ sourceB,
+ references: [refA],
+ parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
+ options: TestOptions.ReleaseExe);
+ if (languageVersion == LanguageVersion.CSharp13)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (11,37): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Console.WriteLine(Run(() => d(3)));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "d(3)").WithLocation(11, 37));
+ }
+ else
+ {
+ var verifier = CompileAndVerify(
+ comp,
+ expectedOutput: """
+ 2
+ 10
+ 2
+ 10
+ """);
+ verifier.VerifyDiagnostics();
+ }
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void OptionalParameter_CollectionInitializer(
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ bool useIn)
+ {
+ string refKind = useIn ? "in" : "";
+ string sourceA = $$"""
+ using System.Collections;
+ using System.Collections.Generic;
+ class MyCollection : IEnumerable
+ {
+ private List> _list = new();
+ public void Add({{refKind}} K k = default, {{refKind}} V v = default) { _list.Add(new(k, v)); }
+ public IEnumerator> GetEnumerator() => _list.GetEnumerator();
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+ }
+ """;
+ string sourceB = """
+ using System;
+ using System.Linq.Expressions;
+ class Program
+ {
+ static void Main()
+ {
+ Report(new MyCollection() { { "one", 1 }, { "two" } });
+ Report(Run(() => new MyCollection() { { "one", 1 }, { "two" } }));
+ }
+ static void Report(MyCollection c)
+ {
+ foreach (var kvp in c)
+ System.Console.WriteLine("{0}, {1}", kvp.Key, kvp.Value);
+ }
+ static T Run(Expression> e)
+ {
+ var f = e.Compile();
+ return f();
+ }
+ }
+ """;
+ var comp = CreateCompilation(
+ [sourceA, sourceB],
+ parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
+ options: TestOptions.ReleaseExe);
+ if (languageVersion == LanguageVersion.CSharp13)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (8,74): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Report(Run(() => new MyCollection() { { "one", 1 }, { "two" } }));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, @"{ ""two"" }").WithLocation(8, 74));
+ }
+ else if (useIn)
+ {
+ // Expression does not support initializers with ref parameters at runtime.
+ comp.VerifyEmitDiagnostics();
+ }
+ else
+ {
+ var verifier = CompileAndVerify(
+ comp,
+ expectedOutput: """
+ one, 1
+ two, 0
+ one, 1
+ two, 0
+ """);
+ verifier.VerifyDiagnostics();
+ }
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void OptionalParameter_LocalFunction(
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion)
+ {
+ string source = """
+ using System;
+ using System.Linq.Expressions;
+ class Program
+ {
+ static void Main()
+ {
+ Expression> e;
+ T Local(T t = default) => t;
+ Local(10);
+ Local();
+ e = () => Local(20);
+ e = () => Local();
+ }
+ }
+ """;
+ var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
+ if (languageVersion == LanguageVersion.CSharp13)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (11,19): error CS8110: An expression tree may not contain a reference to a local function
+ // e = () => Local(20);
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsLocalFunction, "Local(20)").WithLocation(11, 19),
+ // (12,19): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // e = () => Local();
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "Local()").WithLocation(12, 19));
+ }
+ else
+ {
+ comp.VerifyEmitDiagnostics(
+ // (11,19): error CS8110: An expression tree may not contain a reference to a local function
+ // e = () => Local(20);
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsLocalFunction, "Local(20)").WithLocation(11, 19),
+ // (12,19): error CS8110: An expression tree may not contain a reference to a local function
+ // e = () => Local();
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsLocalFunction, "Local()").WithLocation(12, 19));
+ }
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void Decimal(bool preferInterpretation, bool useCompilationReference)
+ {
+ string value = preferInterpretation ? "true" : "false";
+ string sourceA = """
+ public static class A
+ {
+ public static decimal GetValue(decimal d = 100) => d;
+ }
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = AsReference(comp, useCompilationReference);
+
+ string sourceB = $$"""
+ using System;
+ using System.Linq.Expressions;
+ class Program
+ {
+ static void Main()
+ {
+ Console.WriteLine(A.GetValue());
+ Console.WriteLine(Run(() => A.GetValue(200)));
+ Console.WriteLine(Run(() => A.GetValue()));
+ }
+ static T Run(Expression> e)
+ {
+ var f = e.Compile(preferInterpretation: {{value}});
+ return f();
+ }
+ }
+ """;
+ var verifier = CompileAndVerify(
+ sourceB,
+ references: [refA],
+ expectedOutput: """
+ 100
+ 200
+ 100
+ """);
+ verifier.VerifyDiagnostics();
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void DateTime_01(bool preferInterpretation, bool useCompilationReference)
+ {
+ string value = preferInterpretation ? "true" : "false";
+ string sourceA = """
+ using System;
+ using System.Runtime.CompilerServices;
+ using System.Runtime.InteropServices;
+ public static class A
+ {
+ public static DateTime GetValue([Optional][DateTimeConstant(100)] DateTime value) => value;
+ }
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = AsReference(comp, useCompilationReference);
+
+ string sourceB = $$"""
+ using System;
+ using System.Linq.Expressions;
+ class Program
+ {
+ static void Main()
+ {
+ Console.WriteLine(A.GetValue().Ticks);
+ Console.WriteLine(Run(() => A.GetValue(new DateTime(200))).Ticks);
+ Console.WriteLine(Run(() => A.GetValue()).Ticks);
+ }
+ static T Run(Expression> e)
+ {
+ var f = e.Compile(preferInterpretation: {{value}});
+ return f();
+ }
+ }
+ """;
+ var verifier = CompileAndVerify(
+ sourceB,
+ references: [refA],
+ expectedOutput: """
+ 100
+ 200
+ 100
+ """);
+ verifier.VerifyDiagnostics();
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void DateTime_02(bool useCompilationReference)
+ {
+ string sourceA = """
+ using System;
+ using System.Runtime.CompilerServices;
+ public static class A
+ {
+ public static DateTime GetValue([DateTimeConstant(100)] DateTime value) => value;
+ }
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = AsReference(comp, useCompilationReference);
+
+ string sourceB = $$"""
+ using System;
+ using System.Linq.Expressions;
+ class Program
+ {
+ static void Main()
+ {
+ Console.WriteLine(A.GetValue().Ticks);
+ Console.WriteLine(Run(() => A.GetValue()).Ticks);
+ }
+ static T Run(Expression> e)
+ {
+ var f = e.Compile();
+ return f();
+ }
+ }
+ """;
+ comp = CreateCompilation(sourceB, references: [refA]);
+ comp.VerifyEmitDiagnostics(
+ // (7,29): error CS7036: There is no argument given that corresponds to the required parameter 'value' of 'A.GetValue(DateTime)'
+ // Console.WriteLine(A.GetValue().Ticks);
+ Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "GetValue").WithArguments("value", "A.GetValue(System.DateTime)").WithLocation(7, 29),
+ // (8,39): error CS7036: There is no argument given that corresponds to the required parameter 'value' of 'A.GetValue(DateTime)'
+ // Console.WriteLine(Run(() => A.GetValue()).Ticks);
+ Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "GetValue").WithArguments("value", "A.GetValue(System.DateTime)").WithLocation(8, 39));
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void OptionalAndDefaultParameterValue(bool includeOptional, bool includeDefaultParameterValue, bool useCompilationReference)
+ {
+ string sourceA = $$"""
+ using System.Runtime.InteropServices;
+ public static class A
+ {
+ public static int GetValue(
+ {{(includeOptional ? "[Optional]" : "")}}
+ {{(includeDefaultParameterValue ? "[DefaultParameterValue(100)]" : "")}}
+ int value) => value;
+ }
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = AsReference(comp, useCompilationReference);
+
+ string sourceB = """
+ using System;
+ using System.Linq.Expressions;
+ class Program
+ {
+ static void Main()
+ {
+ Console.WriteLine(A.GetValue());
+ Console.WriteLine(Run(() => A.GetValue(200)));
+ Console.WriteLine(Run(() => A.GetValue()));
+ }
+ static T Run(Expression> e)
+ {
+ var f = e.Compile();
+ return f();
+ }
+ }
+ """;
+ comp = CreateCompilation(sourceB, references: [refA], options: TestOptions.ReleaseExe);
+ if (includeOptional)
+ {
+ string optionalValue = includeDefaultParameterValue ? "100" : "0";
+ var verifier = CompileAndVerify(
+ comp,
+ expectedOutput: $$"""
+ {{optionalValue}}
+ 200
+ {{optionalValue}}
+ """);
+ verifier.VerifyDiagnostics();
+ }
+ else
+ {
+ comp.VerifyEmitDiagnostics(
+ // (7,29): error CS7036: There is no argument given that corresponds to the required parameter 'value' of 'A.GetValue(int)'
+ // Console.WriteLine(A.GetValue());
+ Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "GetValue").WithArguments("value", "A.GetValue(int)").WithLocation(7, 29),
+ // (9,39): error CS7036: There is no argument given that corresponds to the required parameter 'value' of 'A.GetValue(int)'
+ // Console.WriteLine(Run(() => A.GetValue()));
+ Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "GetValue").WithArguments("value", "A.GetValue(int)").WithLocation(9, 39));
+ }
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void OptionalParams(bool includeDefaultParameterValue, bool useCompilationReference)
+ {
+ string sourceA = $$"""
+ using System.Runtime.InteropServices;
+ public static class A
+ {
+ public static object[] GetValue(
+ [Optional]
+ {{(includeDefaultParameterValue ? "[DefaultParameterValue(null)]" : "")}}
+ params object[] args) => args;
+ }
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = AsReference(comp, useCompilationReference);
+
+ string sourceB = """
+ using System;
+ using System.Linq.Expressions;
+ class Program
+ {
+ static void Main()
+ {
+ Report(A.GetValue(1, 2, 3));
+ Report(A.GetValue());
+ Report(Run(() => A.GetValue(1, 2, 3)));
+ Report(Run(() => A.GetValue()));
+ }
+ static void Report(object[] args)
+ {
+ Console.WriteLine(args is null ? "null" : args.Length.ToString());
+ }
+ static T Run(Expression> e)
+ {
+ var f = e.Compile();
+ return f();
+ }
+ }
+ """;
+ var verifier = CompileAndVerify(
+ sourceB,
+ references: [refA],
+ expectedOutput: """
+ 3
+ 0
+ 3
+ 0
+ """);
+ verifier.VerifyDiagnostics();
+ }
+ }
+}
From 4c2c64e2a31f31308f1adf8e8793170a22fe863d Mon Sep 17 00:00:00 2001
From: Charles Stoner <10732005+cston@users.noreply.github.com>
Date: Thu, 3 Apr 2025 20:29:54 -0700
Subject: [PATCH 03/14] Fix tests
---
.../Emit/CodeGen/CodeGenExprLambdaTests.cs | 25 ++++--
...xpressionOptionalAndNamedArgumentsTests.cs | 14 ++-
.../Semantic/Semantics/SemanticErrorTests.cs | 88 ++++++++++++++-----
3 files changed, 87 insertions(+), 40 deletions(-)
diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenExprLambdaTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenExprLambdaTests.cs
index 2a479263ed080..8d381df612ae4 100644
--- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenExprLambdaTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenExprLambdaTests.cs
@@ -2595,8 +2595,10 @@ static void Main()
CompileAndVerifyUtil(text, expectedOutput: TrimExpectedOutput(expectedOutput));
}
- [Fact]
- public void MethodCallWithParams3()
+ [Theory]
+ [InlineData(LanguageVersion.CSharp13)]
+ [InlineData(LanguageVersionFacts.CSharpNext)]
+ public void MethodCallWithParams3(LanguageVersion languageVersion)
{
var text =
@"using System;
@@ -2612,12 +2614,19 @@ static void Main()
Console.WriteLine(testExpr);
}
}";
- CreateCompilationWithMscorlib40AndSystemCore(text)
- .VerifyDiagnostics(
- // (10,48): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Expression> testExpr = () => ModAdd2();
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "ModAdd2()")
- );
+ var comp = CreateCompilationWithMscorlib40AndSystemCore(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
+ if (languageVersion == LanguageVersion.CSharp13)
+ {
+ comp.VerifyDiagnostics(
+ // (10,48): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Expression> testExpr = () => ModAdd2();
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "ModAdd2()")
+ );
+ }
+ else
+ {
+ comp.VerifyDiagnostics();
+ }
}
[WorkItem(544419, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544419")]
diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
index 613c71cd4e687..97824f248e6bb 100644
--- a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
@@ -93,9 +93,8 @@ static T Run(Expression> e)
[Theory]
[CombinatorialData]
- public void OptionalParameter_02(bool useIn, bool preferInterpretation, bool useCompilationReference)
+ public void OptionalParameter_02(bool useIn, bool useCompilationReference)
{
- string value = preferInterpretation ? "true" : "false";
string refKind = useIn ? "in" : "";
string sourceA = $$"""
public static class A
@@ -128,7 +127,7 @@ static void Report(object arg)
}
static T Run(Expression> e)
{
- var f = e.Compile(preferInterpretation: {{value}});
+ var f = e.Compile();
return f();
}
}
@@ -149,9 +148,8 @@ static T Run(Expression> e)
[Theory]
[CombinatorialData]
- public void OptionalParameter_AndParams(bool useIn, bool preferInterpretation, bool useCompilationReference)
+ public void OptionalParameter_AndParams(bool useIn, bool useCompilationReference)
{
- string value = preferInterpretation ? "true" : "false";
string refKind = useIn ? "in" : "";
string sourceA = $$"""
public static class A
@@ -183,7 +181,7 @@ static void Report(object arg)
}
static T Run(Expression> e)
{
- var f = e.Compile(preferInterpretation: {{value}});
+ var f = e.Compile();
return f();
}
}
@@ -530,7 +528,7 @@ static void Main()
}
static T Run(Expression> e)
{
- var f = e.Compile(preferInterpretation: {{value}});
+ var f = e.Compile();
return f();
}
}
@@ -576,7 +574,7 @@ static void Main()
}
static T Run(Expression> e)
{
- var f = e.Compile(preferInterpretation: {{value}});
+ var f = e.Compile();
return f();
}
}
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs
index c3a4b47e22d63..2542a831f9e0d 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs
@@ -13134,8 +13134,10 @@ static void Main()
);
}
- [Fact]
- public void CS0854ERR_ExpressionTreeContainsOptionalArgument01()
+ [Theory]
+ [InlineData(LanguageVersion.CSharp13)]
+ [InlineData(LanguageVersionFacts.CSharpNext)]
+ public void CS0854ERR_ExpressionTreeContainsOptionalArgument01(LanguageVersion languageVersion)
{
var text = @"
using System.Linq.Expressions;
@@ -13155,15 +13157,25 @@ public static string Index(int minSessions = 0)
}
}
";
- CreateCompilationWithMscorlib40AndSystemCore(text).VerifyDiagnostics(
- // (10,40): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Expression myET = x => Index();
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "Index()").WithLocation(10, 40)
- );
+ var comp = CreateCompilationWithMscorlib40AndSystemCore(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
+ if (languageVersion == LanguageVersion.CSharp13)
+ {
+ comp.VerifyDiagnostics(
+ // (10,40): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Expression myET = x => Index();
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "Index()").WithLocation(10, 40)
+ );
+ }
+ else
+ {
+ comp.VerifyDiagnostics();
+ }
}
- [Fact]
- public void CS0854ERR_ExpressionTreeContainsOptionalArgument02()
+ [Theory]
+ [InlineData(LanguageVersion.CSharp13)]
+ [InlineData(LanguageVersionFacts.CSharpNext)]
+ public void CS0854ERR_ExpressionTreeContainsOptionalArgument02(LanguageVersion languageVersion)
{
var text =
@"using System;
@@ -13194,19 +13206,39 @@ static void M(A a, B b)
e2 = () => b[4, 5] = null;
}
}";
- CreateCompilationWithMscorlib40AndSystemCore(text).VerifyDiagnostics(
- // (22,20): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "a[0]").WithLocation(22, 20),
- // (25,20): error CS0832: An expression tree may not contain an assignment operator
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsAssignment, "b[3] = null").WithLocation(25, 20),
- // (25,20): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "b[3]").WithLocation(25, 20),
- // (26,20): error CS0832: An expression tree may not contain an assignment operator
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsAssignment, "b[4, 5] = null").WithLocation(26, 20));
+ var comp = CreateCompilationWithMscorlib40AndSystemCore(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
+ if (languageVersion == LanguageVersion.CSharp13)
+ {
+ comp.VerifyDiagnostics(
+ // (22,20): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // e1 = () => a[0];
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "a[0]").WithLocation(22, 20),
+ // (25,20): error CS0832: An expression tree may not contain an assignment operator
+ // e2 = () => b[3] = null;
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsAssignment, "b[3] = null").WithLocation(25, 20),
+ // (25,20): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // e2 = () => b[3] = null;
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "b[3]").WithLocation(25, 20),
+ // (26,20): error CS0832: An expression tree may not contain an assignment operator
+ // e2 = () => b[4, 5] = null;
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsAssignment, "b[4, 5] = null").WithLocation(26, 20));
+ }
+ else
+ {
+ comp.VerifyDiagnostics(
+ // (25,20): error CS0832: An expression tree may not contain an assignment operator
+ // e2 = () => b[3] = null;
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsAssignment, "b[3] = null").WithLocation(25, 20),
+ // (26,20): error CS0832: An expression tree may not contain an assignment operator
+ // e2 = () => b[4, 5] = null;
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsAssignment, "b[4, 5] = null").WithLocation(26, 20));
+ }
}
- [Fact]
- public void CS0854ERR_ExpressionTreeContainsOptionalArgument03()
+ [Theory]
+ [InlineData(LanguageVersion.CSharp13)]
+ [InlineData(LanguageVersionFacts.CSharpNext)]
+ public void CS0854ERR_ExpressionTreeContainsOptionalArgument03(LanguageVersion languageVersion)
{
var text =
@"using System;
@@ -13229,10 +13261,18 @@ public void M() {
() => new Collection { 1 }; // 1
}
}";
- CreateCompilation(text).VerifyDiagnostics(
- // (18,36): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // () => new Collection { 1 }; // 1
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "1").WithLocation(18, 36));
+ var comp = CreateCompilation(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
+ if (languageVersion == LanguageVersion.CSharp13)
+ {
+ comp.VerifyDiagnostics(
+ // (18,36): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // () => new Collection { 1 }; // 1
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "1").WithLocation(18, 36));
+ }
+ else
+ {
+ comp.VerifyDiagnostics();
+ }
}
[Fact]
From 4c1098223d7aa6305307951a202e25eeb417cd0f Mon Sep 17 00:00:00 2001
From: Charles Stoner <10732005+cston@users.noreply.github.com>
Date: Mon, 7 Apr 2025 10:42:32 -0700
Subject: [PATCH 04/14] Expression trees: named arguments
---
.../DiagnosticsPass_ExpressionTrees.cs | 2 +-
...xpressionOptionalAndNamedArgumentsTests.cs | 824 +++++++++++++++++-
2 files changed, 820 insertions(+), 6 deletions(-)
diff --git a/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs b/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs
index afa06a0786fd9..9bda4206fd89c 100644
--- a/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs
@@ -332,7 +332,7 @@ private void VisitCall(
{
Error(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, node);
}
- else if (!argumentNamesOpt.IsDefaultOrEmpty)
+ else if (!argumentNamesOpt.IsDefaultOrEmpty && !_compilation.IsFeatureEnabled(MessageID.IDS_FeatureExpressionOptionalAndNamedArguments)) // PROTOTYPE: Check arguments are in order.
{
Error(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, node);
}
diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
index 97824f248e6bb..3dba9be93f598 100644
--- a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
@@ -9,8 +9,47 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
public class ExpressionOptionalAndNamedArgumentsTests : CSharpTestBase
{
- // PROTOTYPE: Named arguments: Test overloads where the args are in order for one, but not the other.
// PROTOTYPE: Document breaking changes. Are additional overloads now considered (at least those with default parameters)? Test those cases with language version.
+ // PROTOTYPE: Test unrecognized name.
+ // PROTOTYPE: Test name when parameter name is duplicated.
+
+ // PROTOTYPE: Use this for optional argument tests as well.
+ private static string GetUtilities(bool useExpression)
+ {
+ return useExpression ?
+ """
+ using System;
+ using System.Linq.Expressions;
+ public static class Utils
+ {
+ public static void Report(Expression> f)
+ {
+ object value = Run(f);
+ Console.WriteLine(value is null ? "null" : value.ToString());
+ }
+ public static T Run(Expression> e)
+ {
+ var f = e.Compile();
+ return f();
+ }
+ }
+ """ :
+ """
+ using System;
+ public static class Utils
+ {
+ public static void Report(Func f)
+ {
+ object value = Run(f);
+ Console.WriteLine(value is null ? "null" : value.ToString());
+ }
+ public static T Run(Func f)
+ {
+ return f();
+ }
+ }
+ """;
+ }
[Theory]
[CombinatorialData]
@@ -674,10 +713,10 @@ static T Run(Expression> e)
var verifier = CompileAndVerify(
comp,
expectedOutput: $$"""
- {{optionalValue}}
- 200
- {{optionalValue}}
- """);
+ {{optionalValue}}
+ 200
+ {{optionalValue}}
+ """);
verifier.VerifyDiagnostics();
}
else
@@ -743,5 +782,780 @@ static T Run(Expression> e)
""");
verifier.VerifyDiagnostics();
}
+
+ [Theory]
+ [CombinatorialData]
+ public void NamedArgument_01(
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ bool useExpression,
+ bool useCompilationReference)
+ {
+ string sourceA = $$"""
+ public static class A
+ {
+ public static T GetFirst(T first, T second) => first;
+ }
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = AsReference(comp, useCompilationReference);
+
+ string sourceB1 = $$"""
+ class Program
+ {
+ static void Main()
+ {
+ Utils.Report(() => A.GetFirst(1, second:2));
+ Utils.Report(() => A.GetFirst(first: 1, 2));
+ Utils.Report(() => A.GetFirst(first: 1, second:2));
+ }
+ }
+ """;
+ comp = CreateCompilation(
+ [sourceB1, GetUtilities(useExpression)],
+ references: [refA],
+ parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
+ options: TestOptions.ReleaseExe);
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (5,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => A.GetFirst(1, second:2));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(1, second:2)").WithLocation(5, 28),
+ // (6,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => A.GetFirst(first: 1, 2));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(first: 1, 2)").WithLocation(6, 28),
+ // (7,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => A.GetFirst(first: 1, second:2));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(first: 1, second:2)").WithLocation(7, 28));
+ }
+ else
+ {
+ var verifier = CompileAndVerify(
+ comp,
+ expectedOutput: """
+ 1
+ 1
+ 1
+ """);
+ verifier.VerifyDiagnostics();
+ }
+
+ string sourceB2 = $$"""
+ class Program
+ {
+ static void Main()
+ {
+ Utils.Report(() => A.GetFirst(second:2, first: 1));
+ }
+ }
+ """;
+ comp = CreateCompilation(
+ [sourceB2, GetUtilities(useExpression)],
+ references: [refA],
+ parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
+ options: TestOptions.ReleaseExe);
+ if (useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (5,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => A.GetFirst(second:2, first: 1));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(second:2, first: 1)").WithLocation(5, 28));
+ }
+ else
+ {
+ var verifier = CompileAndVerify(
+ comp,
+ expectedOutput: """
+ 1
+ """);
+ verifier.VerifyDiagnostics();
+ }
+
+ string sourceB3 = $$"""
+ class Program
+ {
+ static void Main()
+ {
+ Utils.Report(() => A.GetFirst(2, first: 1));
+ Utils.Report(() => A.GetFirst(second:2, 1));
+ }
+ }
+ """;
+ comp = CreateCompilation(
+ [sourceB3, GetUtilities(useExpression)],
+ references: [refA],
+ parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
+ options: TestOptions.ReleaseExe);
+ comp.VerifyEmitDiagnostics(
+ // (5,47): error CS1744: Named argument 'first' specifies a parameter for which a positional argument has already been given
+ // Utils.Report(() => A.GetFirst(2, first: 1));
+ Diagnostic(ErrorCode.ERR_NamedArgumentUsedInPositional, "first").WithArguments("first").WithLocation(5, 47),
+ // (6,44): error CS8323: Named argument 'second' is used out-of-position but is followed by an unnamed argument
+ // Utils.Report(() => A.GetFirst(second:2, 1));
+ Diagnostic(ErrorCode.ERR_BadNonTrailingNamedArgument, "second").WithArguments("second").WithLocation(6, 44));
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void NamedArgument_02(
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ bool useExpression,
+ bool useCompilationReference)
+ {
+ string sourceA = $$"""
+ public static class A
+ {
+ public static T GetFirst(T first = default, T second = default, T third = default) => first;
+ }
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = AsReference(comp, useCompilationReference);
+
+ string sourceB1 = $$"""
+ class Program
+ {
+ static void Main()
+ {
+ Utils.Report(() => A.GetFirst
+
+ An expression tree may not contain a named argument specification out of position
+ An expression tree may not contain a named argument specification out of position
+
+
An expression tree may not contain a pattern System.Index or System.Range indexer access
Strom výrazů možná neobsahuje vzor přístupu indexeru System.Index nebo System.Range.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
index 301229db797c5..e053bf86aef4e 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
@@ -742,6 +742,11 @@
Eine Ausdrucksbaumstruktur darf keine Handler-Konvertierung einer interpolierten Zeichenfolge enthalten.
+
+ An expression tree may not contain a named argument specification out of position
+ An expression tree may not contain a named argument specification out of position
+
+
An expression tree may not contain a pattern System.Index or System.Range indexer access
Eine Ausdrucksbaumstruktur darf keinen System.Index- oder System.Range-Musterindexerzugriff enthalten.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
index 83575dbefe3a2..2391b36dafa0d 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
@@ -742,6 +742,11 @@
Un árbol de (la) expresión no puede contener una conversión de controlador de cadena interpolada.
+
+ An expression tree may not contain a named argument specification out of position
+ An expression tree may not contain a named argument specification out of position
+
+
An expression tree may not contain a pattern System.Index or System.Range indexer access
Un árbol de expresión no puede contener un patrón System.Index o un acceso a indizador System.Range.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
index a80bcf844e55d..66522d1778117 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
@@ -742,6 +742,11 @@
Une arborescence de l’expression ne peut pas contenir une conversion de gestionnaire de chaîne interpolée.
+
+ An expression tree may not contain a named argument specification out of position
+ An expression tree may not contain a named argument specification out of position
+
+
An expression tree may not contain a pattern System.Index or System.Range indexer access
Une arborescence de l'expression ne peut pas contenir de modèle d'accès à l'indexeur System.Index ou System.Range
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
index 134add8f363ab..8c023246bf9fb 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
@@ -742,6 +742,11 @@
Un albero delle espressioni non può contenere una conversione del gestore di stringhe interpolate.
+
+ An expression tree may not contain a named argument specification out of position
+ An expression tree may not contain a named argument specification out of position
+
+
An expression tree may not contain a pattern System.Index or System.Range indexer access
Un albero delle espressioni non può contenere un accesso a indicizzatore System.Index o System.Range di criterio
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
index e50469348d849..347c9fdb345ed 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
@@ -742,6 +742,11 @@
式ツリーには、補間された文字列ハンドラー変換を含めることはできません。
+
+ An expression tree may not contain a named argument specification out of position
+ An expression tree may not contain a named argument specification out of position
+
+
An expression tree may not contain a pattern System.Index or System.Range indexer access
式ツリーに、System.Index または System.Range インデクサー アクセスのパターンを含めることはできません
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
index 43c44b02c76e2..1a2df1b56ecc3 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
@@ -742,6 +742,11 @@
식 트리에는 보간된 문자열 처리기 변환이 포함될 수 없습니다.
+
+ An expression tree may not contain a named argument specification out of position
+ An expression tree may not contain a named argument specification out of position
+
+
An expression tree may not contain a pattern System.Index or System.Range indexer access
식 트리에는 System.Index 또는 System.Range 패턴의 인덱서 액세스를 포함할 수 없습니다.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
index b3decad616b05..e3f673d108874 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
@@ -742,6 +742,11 @@
Drzewo wyrażenia nie może zawierać konwersji procedury obsługi ciągu interpolowanego.
+
+ An expression tree may not contain a named argument specification out of position
+ An expression tree may not contain a named argument specification out of position
+
+
An expression tree may not contain a pattern System.Index or System.Range indexer access
Drzewo wyrażenia nie może zawierać dostępu do indeksatora z wzorcem System.Index lub System.Range
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
index a85e5effa2662..2852841fa1e68 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
@@ -742,6 +742,11 @@
Uma árvore de expressão pode não conter uma conversão de manipulador de cadeia de caracteres interpolada.
+
+ An expression tree may not contain a named argument specification out of position
+ An expression tree may not contain a named argument specification out of position
+
+
An expression tree may not contain a pattern System.Index or System.Range indexer access
Uma árvore de expressão não pode conter um padrão System.Index ou acesso do indexador System.Range
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
index 55919fd6242c5..1a43834fcad56 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
@@ -742,6 +742,11 @@
Дерево выражения не может содержать преобразование обработчика интерполированных строк.
+
+ An expression tree may not contain a named argument specification out of position
+ An expression tree may not contain a named argument specification out of position
+
+
An expression tree may not contain a pattern System.Index or System.Range indexer access
Дерево выражения не может содержать доступ к индексатору System.Index или System.Range шаблона.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
index 9bd8e69dbf874..8b54c792b7466 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
@@ -742,6 +742,11 @@
Bir ifade ağacı, düz metin arasına kod eklenmiş dize işleyicisi dönüşümü içeremez.
+
+ An expression tree may not contain a named argument specification out of position
+ An expression tree may not contain a named argument specification out of position
+
+
An expression tree may not contain a pattern System.Index or System.Range indexer access
İfade ağacı, desen System.Index veya System.Range dizin oluşturucu erişimi içeremez
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
index 9170d809cbcb0..2f4dd751e9457 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
@@ -742,6 +742,11 @@
表达式树可能不包含内插字符串处理程序转换。
+
+ An expression tree may not contain a named argument specification out of position
+ An expression tree may not contain a named argument specification out of position
+
+
An expression tree may not contain a pattern System.Index or System.Range indexer access
表达式树不能包含模式 System.Index 或 System.Range 索引器访问
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
index 1e6772bc6a43b..4ee88b61a387e 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
@@ -742,6 +742,11 @@
運算式樹狀架構不可包含差補字串處理常式轉換。
+
+ An expression tree may not contain a named argument specification out of position
+ An expression tree may not contain a named argument specification out of position
+
+
An expression tree may not contain a pattern System.Index or System.Range indexer access
運算式樹狀架構不可包含 System.Index 或 System.Range 索引子存取模式
diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
index 3dba9be93f598..110b4a93bd19e 100644
--- a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
@@ -3,17 +3,13 @@
// See the LICENSE file in the project root for more information.
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
+using Microsoft.CodeAnalysis.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
public class ExpressionOptionalAndNamedArgumentsTests : CSharpTestBase
{
- // PROTOTYPE: Document breaking changes. Are additional overloads now considered (at least those with default parameters)? Test those cases with language version.
- // PROTOTYPE: Test unrecognized name.
- // PROTOTYPE: Test name when parameter name is duplicated.
-
- // PROTOTYPE: Use this for optional argument tests as well.
private static string GetUtilities(bool useExpression)
{
return useExpression ?
@@ -56,6 +52,7 @@ public static T Run(Func f)
public void OptionalParameter_01(
[CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
bool useIn,
+ bool useExpression,
bool useCompilationReference)
{
string refKind = useIn ? "in" : "";
@@ -69,8 +66,6 @@ public static class A
var refA = AsReference(comp, useCompilationReference);
string sourceB = $$"""
- using System;
- using System.Linq.Expressions;
struct S
{
}
@@ -78,41 +73,29 @@ class Program
{
static void Main()
{
- Report(A.GetValue());
- Report(A.GetValue());
- Report(A.GetValue());
- Report(Run(() => A.GetValue()));
- Report(Run(() => A.GetValue()));
- Report(Run(() => A.GetValue()));
- }
- static void Report(object arg)
- {
- Console.WriteLine(arg is null ? "null" : arg.ToString());
- }
- static T Run(Expression> e)
- {
- var f = e.Compile();
- return f();
+ Utils.Report(() => A.GetValue());
+ Utils.Report(() => A.GetValue());
+ Utils.Report(() => A.GetValue());
}
}
""";
comp = CreateCompilation(
- sourceB,
+ [sourceB, GetUtilities(useExpression)],
references: [refA],
parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
options: TestOptions.ReleaseExe);
- if (languageVersion == LanguageVersion.CSharp13)
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
{
comp.VerifyEmitDiagnostics(
- // (13,26): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Report(Run(() => A.GetValue()));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetValue()").WithLocation(13, 26),
- // (14,26): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Report(Run(() => A.GetValue()));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetValue()").WithLocation(14, 26),
- // (15,26): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Report(Run(() => A.GetValue()));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetValue()").WithLocation(15, 26));
+ // (8,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Utils.Report(() => A.GetValue());
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetValue()").WithLocation(8, 28),
+ // (9,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Utils.Report(() => A.GetValue());
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetValue()").WithLocation(9, 28),
+ // (10,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Utils.Report(() => A.GetValue());
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetValue()").WithLocation(10, 28));
}
else
{
@@ -122,9 +105,6 @@ static T Run(Expression> e)
0
null
S
- 0
- null
- S
""");
verifier.VerifyDiagnostics();
}
@@ -132,7 +112,10 @@ static T Run(Expression> e)
[Theory]
[CombinatorialData]
- public void OptionalParameter_02(bool useIn, bool useCompilationReference)
+ public void OptionalParameter_02(
+ bool useIn,
+ bool useExpression,
+ bool useCompilationReference)
{
string refKind = useIn ? "in" : "";
string sourceA = $$"""
@@ -147,37 +130,20 @@ public static class A
var refA = AsReference(comp, useCompilationReference);
string sourceB = $$"""
- using System;
- using System.Linq.Expressions;
class Program
{
static void Main()
{
- Report(A.GetIntValue());
- Report(A.GetStringValue());
- Report(A.GetObjectValue());
- Report(Run(() => A.GetIntValue()));
- Report(Run(() => A.GetStringValue()));
- Report(Run(() => A.GetObjectValue()));
- }
- static void Report(object arg)
- {
- Console.WriteLine(arg is null ? "null" : arg.ToString());
- }
- static T Run(Expression> e)
- {
- var f = e.Compile();
- return f();
+ Utils.Report(() => A.GetIntValue());
+ Utils.Report(() => A.GetStringValue());
+ Utils.Report(() => A.GetObjectValue());
}
}
""";
var verifier = CompileAndVerify(
- sourceB,
+ [sourceB, GetUtilities(useExpression)],
references: [refA],
expectedOutput: """
- 10
- default
- null
10
default
null
@@ -187,7 +153,10 @@ static T Run(Expression> e)
[Theory]
[CombinatorialData]
- public void OptionalParameter_AndParams(bool useIn, bool useCompilationReference)
+ public void OptionalParameter_AndParams(
+ bool useIn,
+ bool useExpression,
+ bool useCompilationReference)
{
string refKind = useIn ? "in" : "";
string sourceA = $$"""
@@ -200,8 +169,6 @@ public static class A
var refA = AsReference(comp, useCompilationReference);
string sourceB = $$"""
- using System;
- using System.Linq.Expressions;
struct S
{
}
@@ -209,28 +176,15 @@ class Program
{
static void Main()
{
- Report(A.GetValue(1));
- Report(A.GetValue(2, 3, 4));
- Report(Run(() => A.GetValue(1)));
- Report(Run(() => A.GetValue(2, 3, 4)));
- }
- static void Report(object arg)
- {
- Console.WriteLine(arg is null ? "null" : arg.ToString());
- }
- static T Run(Expression> e)
- {
- var f = e.Compile();
- return f();
+ Utils.Report(() => A.GetValue(1));
+ Utils.Report(() => A.GetValue(2, 3, 4));
}
}
""";
var verifier = CompileAndVerify(
- sourceB,
+ [sourceB, GetUtilities(useExpression)],
references: [refA],
expectedOutput: """
- 0
- 3
0
3
""");
@@ -241,7 +195,7 @@ static T Run(Expression> e)
[CombinatorialData]
public void OptionalParameter_Constructor(
[CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
- bool useCompilationReference)
+ bool useExpression)
{
string sourceA = $$"""
public class A
@@ -249,48 +203,36 @@ public class A
public readonly string X;
public readonly int Y;
public A(string x = "default", in int y = 10) { X = x; Y = y; }
+ public override string ToString() => $"({X}, {Y})";
}
""";
var comp = CreateCompilation(sourceA);
- var refA = AsReference(comp, useCompilationReference);
+ var refA = comp.EmitToImageReference();
string sourceB = $$"""
- using System;
- using System.Linq.Expressions;
class Program
{
static void Main()
{
- Report(new A("str"));
- Report(new A());
- Report(Run(() => new A("str")));
- Report(Run(() => new A()));
- }
- static void Report(A a)
- {
- Console.WriteLine((a.X, a.Y));
- }
- static T Run(Expression> e)
- {
- var f = e.Compile();
- return f();
+ Utils.Report(() => new A("str"));
+ Utils.Report(() => new A());
}
}
""";
comp = CreateCompilation(
- sourceB,
+ [sourceB, GetUtilities(useExpression)],
references: [refA],
parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
options: TestOptions.ReleaseExe);
- if (languageVersion == LanguageVersion.CSharp13)
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
{
comp.VerifyEmitDiagnostics(
- // (9,26): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Report(Run(() => new A("str")));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, @"new A(""str"")").WithLocation(9, 26),
- // (10,26): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Report(Run(() => new A()));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "new A()").WithLocation(10, 26));
+ // (5,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Utils.Report(() => new A("str"));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, @"new A(""str"")").WithLocation(5, 28),
+ // (6,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Utils.Report(() => new A());
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "new A()").WithLocation(6, 28));
}
else
{
@@ -299,8 +241,6 @@ static T Run(Expression> e)
expectedOutput: """
(str, 10)
(default, 10)
- (str, 10)
- (default, 10)
""");
verifier.VerifyDiagnostics();
}
@@ -310,7 +250,7 @@ static T Run(Expression> e)
[CombinatorialData]
public void OptionalParameter_Indexer(
[CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
- bool useCompilationReference)
+ bool useExpression)
{
string sourceA = $$"""
public class A
@@ -319,39 +259,30 @@ public class A
}
""";
var comp = CreateCompilation(sourceA);
- var refA = AsReference(comp, useCompilationReference);
+ var refA = comp.EmitToImageReference();
string sourceB = $$"""
- using System;
- using System.Linq.Expressions;
class Program
{
static void Main()
{
var a = new A();
- Console.WriteLine(a[1, 2]);
- Console.WriteLine(a[3]);
- Console.WriteLine(Run(() => a[1, 2]));
- Console.WriteLine(Run(() => a[3]));
- }
- static T Run(Expression> e)
- {
- var f = e.Compile();
- return f();
+ Utils.Report(() => a[1, 2]);
+ Utils.Report(() => a[3]);
}
}
""";
comp = CreateCompilation(
- sourceB,
+ [sourceB, GetUtilities(useExpression)],
references: [refA],
parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
options: TestOptions.ReleaseExe);
- if (languageVersion == LanguageVersion.CSharp13)
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
{
comp.VerifyEmitDiagnostics(
- // (11,37): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Console.WriteLine(Run(() => a[3]));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "a[3]").WithLocation(11, 37));
+ // (7,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Utils.Report(() => a[3]);
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "a[3]").WithLocation(7, 28));
}
else
{
@@ -360,8 +291,6 @@ static T Run(Expression> e)
expectedOutput: """
2
10
- 2
- 10
""");
verifier.VerifyDiagnostics();
}
@@ -371,46 +300,37 @@ static T Run(Expression> e)
[CombinatorialData]
public void OptionalParameter_Delegate(
[CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
- bool useCompilationReference)
+ bool useExpression)
{
string sourceA = $$"""
public delegate int D(int x, in int y = 10);
""";
var comp = CreateCompilation(sourceA);
- var refA = AsReference(comp, useCompilationReference);
+ var refA = comp.EmitToImageReference();
string sourceB = $$"""
- using System;
- using System.Linq.Expressions;
class Program
{
static void Main()
{
D d = F;
- Console.WriteLine(d(1, 2));
- Console.WriteLine(d(3));
- Console.WriteLine(Run(() => d(1, 2)));
- Console.WriteLine(Run(() => d(3)));
- }
- static T Run(Expression> e)
- {
- var f = e.Compile();
- return f();
+ Utils.Report(() => d(1, 2));
+ Utils.Report(() => d(3));
}
static T F(T x, in T y) => y;
}
""";
comp = CreateCompilation(
- sourceB,
+ [sourceB, GetUtilities(useExpression)],
references: [refA],
parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
options: TestOptions.ReleaseExe);
- if (languageVersion == LanguageVersion.CSharp13)
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
{
comp.VerifyEmitDiagnostics(
- // (11,37): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Console.WriteLine(Run(() => d(3)));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "d(3)").WithLocation(11, 37));
+ // (7,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Utils.Report(() => d(3));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "d(3)").WithLocation(7, 28));
}
else
{
@@ -419,8 +339,6 @@ static T Run(Expression> e)
expectedOutput: """
2
10
- 2
- 10
""");
verifier.VerifyDiagnostics();
}
@@ -430,52 +348,51 @@ static T Run(Expression> e)
[CombinatorialData]
public void OptionalParameter_CollectionInitializer(
[CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ bool useExpression,
bool useIn)
{
string refKind = useIn ? "in" : "";
string sourceA = $$"""
using System.Collections;
using System.Collections.Generic;
+ using System.Text;
class MyCollection : IEnumerable
{
private List> _list = new();
public void Add({{refKind}} K k = default, {{refKind}} V v = default) { _list.Add(new(k, v)); }
public IEnumerator> GetEnumerator() => _list.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+ public override string ToString()
+ {
+ var builder = new StringBuilder();
+ foreach (var kvp in this)
+ {
+ if (builder.Length > 0) builder.Append(", ");
+ builder.AppendFormat("({0}, {1})", kvp.Key, kvp.Value);
+ }
+ return builder.ToString();
+ }
}
""";
string sourceB = """
- using System;
- using System.Linq.Expressions;
class Program
{
static void Main()
{
- Report(new MyCollection() { { "one", 1 }, { "two" } });
- Report(Run(() => new MyCollection() { { "one", 1 }, { "two" } }));
- }
- static void Report(MyCollection c)
- {
- foreach (var kvp in c)
- System.Console.WriteLine("{0}, {1}", kvp.Key, kvp.Value);
- }
- static T Run(Expression> e)
- {
- var f = e.Compile();
- return f();
+ Utils.Report(() => new MyCollection() { { "one", 1 }, { "two" } });
}
}
""";
var comp = CreateCompilation(
- [sourceA, sourceB],
+ [sourceA, sourceB, GetUtilities(useExpression)],
parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
options: TestOptions.ReleaseExe);
- if (languageVersion == LanguageVersion.CSharp13)
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
{
comp.VerifyEmitDiagnostics(
- // (8,74): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Report(Run(() => new MyCollection() { { "one", 1 }, { "two" } }));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, @"{ ""two"" }").WithLocation(8, 74));
+ // (5,76): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Utils.Report(() => new MyCollection() { { "one", 1 }, { "two" } });
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, @"{ ""two"" }").WithLocation(5, 76));
}
else if (useIn)
{
@@ -486,12 +403,7 @@ static T Run(Expression> e)
{
var verifier = CompileAndVerify(
comp,
- expectedOutput: """
- one, 1
- two, 0
- one, 1
- two, 0
- """);
+ expectedOutput: "(one, 1), (two, 0)");
verifier.VerifyDiagnostics();
}
}
@@ -542,9 +454,10 @@ static void Main()
[Theory]
[CombinatorialData]
- public void Decimal(bool preferInterpretation, bool useCompilationReference)
+ public void Decimal(
+ bool useExpression,
+ bool useCompilationReference)
{
- string value = preferInterpretation ? "true" : "false";
string sourceA = """
public static class A
{
@@ -555,28 +468,19 @@ public static class A
var refA = AsReference(comp, useCompilationReference);
string sourceB = $$"""
- using System;
- using System.Linq.Expressions;
class Program
{
static void Main()
{
- Console.WriteLine(A.GetValue());
- Console.WriteLine(Run(() => A.GetValue(200)));
- Console.WriteLine(Run(() => A.GetValue()));
- }
- static T Run(Expression> e)
- {
- var f = e.Compile();
- return f();
+ Utils.Report(() => A.GetValue(200));
+ Utils.Report(() => A.GetValue());
}
}
""";
var verifier = CompileAndVerify(
- sourceB,
+ [sourceB, GetUtilities(useExpression)],
references: [refA],
expectedOutput: """
- 100
200
100
""");
@@ -585,9 +489,10 @@ static T Run(Expression> e)
[Theory]
[CombinatorialData]
- public void DateTime_01(bool preferInterpretation, bool useCompilationReference)
+ public void DateTime_01(
+ bool useExpression,
+ bool useCompilationReference)
{
- string value = preferInterpretation ? "true" : "false";
string sourceA = """
using System;
using System.Runtime.CompilerServices;
@@ -602,27 +507,19 @@ public static class A
string sourceB = $$"""
using System;
- using System.Linq.Expressions;
class Program
{
static void Main()
{
- Console.WriteLine(A.GetValue().Ticks);
- Console.WriteLine(Run(() => A.GetValue(new DateTime(200))).Ticks);
- Console.WriteLine(Run(() => A.GetValue()).Ticks);
- }
- static T Run(Expression> e)
- {
- var f = e.Compile();
- return f();
+ Utils.Report(() => A.GetValue(new DateTime(200)).Ticks);
+ Utils.Report(() => A.GetValue().Ticks);
}
}
""";
var verifier = CompileAndVerify(
- sourceB,
+ [sourceB, GetUtilities(useExpression)],
references: [refA],
expectedOutput: """
- 100
200
100
""");
@@ -631,7 +528,9 @@ static T Run(Expression> e)
[Theory]
[CombinatorialData]
- public void DateTime_02(bool useCompilationReference)
+ public void DateTime_02(
+ bool useExpression,
+ bool useCompilationReference)
{
string sourceA = """
using System;
@@ -645,35 +544,30 @@ public static class A
var refA = AsReference(comp, useCompilationReference);
string sourceB = $$"""
- using System;
- using System.Linq.Expressions;
class Program
{
static void Main()
{
- Console.WriteLine(A.GetValue().Ticks);
- Console.WriteLine(Run(() => A.GetValue()).Ticks);
- }
- static T Run(Expression> e)
- {
- var f = e.Compile();
- return f();
+ Utils.Report(() => A.GetValue().Ticks);
}
}
""";
- comp = CreateCompilation(sourceB, references: [refA]);
+ comp = CreateCompilation(
+ [sourceB, GetUtilities(useExpression)],
+ references: [refA]);
comp.VerifyEmitDiagnostics(
- // (7,29): error CS7036: There is no argument given that corresponds to the required parameter 'value' of 'A.GetValue(DateTime)'
- // Console.WriteLine(A.GetValue().Ticks);
- Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "GetValue").WithArguments("value", "A.GetValue(System.DateTime)").WithLocation(7, 29),
- // (8,39): error CS7036: There is no argument given that corresponds to the required parameter 'value' of 'A.GetValue(DateTime)'
- // Console.WriteLine(Run(() => A.GetValue()).Ticks);
- Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "GetValue").WithArguments("value", "A.GetValue(System.DateTime)").WithLocation(8, 39));
+ // (5,30): error CS7036: There is no argument given that corresponds to the required parameter 'value' of 'A.GetValue(DateTime)'
+ // Utils.Report(() => A.GetValue().Ticks);
+ Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "GetValue").WithArguments("value", "A.GetValue(System.DateTime)").WithLocation(5, 30));
}
[Theory]
[CombinatorialData]
- public void OptionalAndDefaultParameterValue(bool includeOptional, bool includeDefaultParameterValue, bool useCompilationReference)
+ public void OptionalAndDefaultParameterValue(
+ bool includeOptional,
+ bool includeDefaultParameterValue,
+ bool useExpression,
+ bool useCompilationReference)
{
string sourceA = $$"""
using System.Runtime.InteropServices;
@@ -689,94 +583,75 @@ public static int GetValue(
var refA = AsReference(comp, useCompilationReference);
string sourceB = """
- using System;
- using System.Linq.Expressions;
class Program
{
static void Main()
{
- Console.WriteLine(A.GetValue());
- Console.WriteLine(Run(() => A.GetValue(200)));
- Console.WriteLine(Run(() => A.GetValue()));
- }
- static T Run(Expression> e)
- {
- var f = e.Compile();
- return f();
+ Utils.Report(() => A.GetValue(200));
+ Utils.Report(() => A.GetValue());
}
}
""";
- comp = CreateCompilation(sourceB, references: [refA], options: TestOptions.ReleaseExe);
+ comp = CreateCompilation(
+ [sourceB, GetUtilities(useExpression)],
+ references: [refA],
+ options: TestOptions.ReleaseExe);
if (includeOptional)
{
- string optionalValue = includeDefaultParameterValue ? "100" : "0";
var verifier = CompileAndVerify(
comp,
expectedOutput: $$"""
- {{optionalValue}}
200
- {{optionalValue}}
+ {{(includeDefaultParameterValue ? "100" : "0")}}
""");
verifier.VerifyDiagnostics();
}
else
{
comp.VerifyEmitDiagnostics(
- // (7,29): error CS7036: There is no argument given that corresponds to the required parameter 'value' of 'A.GetValue(int)'
- // Console.WriteLine(A.GetValue());
- Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "GetValue").WithArguments("value", "A.GetValue(int)").WithLocation(7, 29),
- // (9,39): error CS7036: There is no argument given that corresponds to the required parameter 'value' of 'A.GetValue(int)'
- // Console.WriteLine(Run(() => A.GetValue()));
- Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "GetValue").WithArguments("value", "A.GetValue(int)").WithLocation(9, 39));
+ // (6,30): error CS7036: There is no argument given that corresponds to the required parameter 'value' of 'A.GetValue(int)'
+ // Utils.Report(() => A.GetValue());
+ Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "GetValue").WithArguments("value", "A.GetValue(int)").WithLocation(6, 30));
}
}
[Theory]
[CombinatorialData]
- public void OptionalParams(bool includeDefaultParameterValue, bool useCompilationReference)
+ public void OptionalParams(
+ bool includeDefaultParameterValue,
+ bool useExpression,
+ bool useCompilationReference)
{
string sourceA = $$"""
using System.Runtime.InteropServices;
public static class A
{
- public static object[] GetValue(
+ public static string GetValue(
[Optional]
{{(includeDefaultParameterValue ? "[DefaultParameterValue(null)]" : "")}}
- params object[] args) => args;
+ params object[] args)
+ {
+ return (args is null) ? "null" : args.Length.ToString();
+ }
}
""";
var comp = CreateCompilation(sourceA);
var refA = AsReference(comp, useCompilationReference);
string sourceB = """
- using System;
- using System.Linq.Expressions;
class Program
{
static void Main()
{
- Report(A.GetValue(1, 2, 3));
- Report(A.GetValue());
- Report(Run(() => A.GetValue(1, 2, 3)));
- Report(Run(() => A.GetValue()));
- }
- static void Report(object[] args)
- {
- Console.WriteLine(args is null ? "null" : args.Length.ToString());
- }
- static T Run(Expression> e)
- {
- var f = e.Compile();
- return f();
+ Utils.Report(() => A.GetValue(1, 2, 3));
+ Utils.Report(() => A.GetValue());
}
}
""";
var verifier = CompileAndVerify(
- sourceB,
+ [sourceB, GetUtilities(useExpression)],
references: [refA],
expectedOutput: """
- 3
- 0
3
0
""");
@@ -854,13 +729,20 @@ static void Main()
references: [refA],
parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
options: TestOptions.ReleaseExe);
- if (useExpression)
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
{
comp.VerifyEmitDiagnostics(
// (5,28): error CS0853: An expression tree may not contain a named argument specification
// Utils.Report(() => A.GetFirst(second:2, first: 1));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(second:2, first: 1)").WithLocation(5, 28));
}
+ else if (useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (5,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => A.GetFirst(second:2, first: 1));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(second:2, first: 1)").WithLocation(5, 28));
+ }
else
{
var verifier = CompileAndVerify(
@@ -992,7 +874,7 @@ static void Main()
references: [refA],
parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
options: TestOptions.ReleaseExe);
- if (useExpression)
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
{
comp.VerifyEmitDiagnostics(
// (5,28): error CS0853: An expression tree may not contain a named argument specification
@@ -1017,6 +899,28 @@ static void Main()
// Utils.Report(() => A.GetFirst());
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst()").WithLocation(11, 28));
}
+ else if (useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (5,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => A.GetFirst(third:3, second: 2, first: 1));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(third:3, second: 2, first: 1)").WithLocation(5, 28),
+ // (6,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => A.GetFirst(second:2, first: 1));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(second:2, first: 1)").WithLocation(6, 28),
+ // (7,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => A.GetFirst(second:2, third: 3));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(second:2, third: 3)").WithLocation(7, 28),
+ // (8,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => A.GetFirst(second:2));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(second:2)").WithLocation(8, 28),
+ // (9,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => A.GetFirst(third:3, second: 2));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(third:3, second: 2)").WithLocation(9, 28),
+ // (10,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => A.GetFirst(third:3));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(third:3)").WithLocation(10, 28));
+ }
else
{
var verifier = CompileAndVerify(
@@ -1120,12 +1024,19 @@ static void Main()
references: [refA],
parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
options: TestOptions.ReleaseExe);
- if (useExpression)
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (5,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => A.GetFirstAndParamsLength(more: default, first: 1));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirstAndParamsLength(more: default, first: 1)").WithLocation(5, 28));
+ }
+ else if (useExpression)
{
comp.VerifyEmitDiagnostics(
- // (5,28): error CS0853: An expression tree may not contain a named argument specification
- // Utils.Report(() => A.GetFirstAndParamsLength(more: default, first: 1));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirstAndParamsLength(more: default, first: 1)").WithLocation(5, 28));
+ // (5,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => A.GetFirstAndParamsLength(more: default, first: 1));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirstAndParamsLength(more: default, first: 1)").WithLocation(5, 28));
}
else
{
@@ -1292,7 +1203,7 @@ static void Main()
references: [refA],
parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
options: TestOptions.ReleaseExe);
- if (useExpression)
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
{
comp.VerifyEmitDiagnostics(
// (5,28): error CS0853: An expression tree may not contain a named argument specification
@@ -1320,6 +1231,31 @@ static void Main()
// Utils.Report(() => A.GetSecondAndParamsLength(more: new[] { 3, 4 }, second: 2, first: 1));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetSecondAndParamsLength(more: new[] { 3, 4 }, second: 2, first: 1)").WithLocation(12, 28));
}
+ else if (useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (6,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => A.GetSecondAndParamsLength(first: 1, more: default, second: 2));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetSecondAndParamsLength(first: 1, more: default, second: 2)").WithLocation(6, 28),
+ // (7,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => A.GetSecondAndParamsLength(first: 1, more: default));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetSecondAndParamsLength(first: 1, more: default)").WithLocation(7, 28),
+ // (8,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => A.GetSecondAndParamsLength(second: 2));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetSecondAndParamsLength(second: 2)").WithLocation(8, 28),
+ // (9,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => A.GetSecondAndParamsLength(second: 2, first: 1));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetSecondAndParamsLength(second: 2, first: 1)").WithLocation(9, 28),
+ // (10,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => A.GetSecondAndParamsLength(second: 2, more: default));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetSecondAndParamsLength(second: 2, more: default)").WithLocation(10, 28),
+ // (11,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => A.GetSecondAndParamsLength(more: new[] { 3, 4 }));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetSecondAndParamsLength(more: new[] { 3, 4 })").WithLocation(11, 28),
+ // (12,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => A.GetSecondAndParamsLength(more: new[] { 3, 4 }, second: 2, first: 1));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetSecondAndParamsLength(more: new[] { 3, 4 }, second: 2, first: 1)").WithLocation(12, 28));
+ }
else
{
var verifier = CompileAndVerify(
@@ -1433,10 +1369,6 @@ static void Main()
{
Utils.Report(() => A.GetFirst(second: 2, first: 1));
Utils.Report(() => A.GetFirst(first: "one", second: "two"));
- Utils.Report(() => A.GetFirst(first: default, default));
- Utils.Report(() => A.GetFirst(second: default, default));
- Utils.Report(() => A.GetFirst(default, second: default));
- Utils.Report(() => A.GetFirst(default, first: default));
}
}
""";
@@ -1453,27 +1385,71 @@ static void Main()
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(second: 2, first: 1)").WithLocation(5, 28),
// (6,28): error CS0853: An expression tree may not contain a named argument specification
// Utils.Report(() => A.GetFirst(first: "one", second: "two"));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, @"A.GetFirst(first: ""one"", second: ""two"")").WithLocation(6, 28),
- // (7,28): error CS0853: An expression tree may not contain a named argument specification
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, @"A.GetFirst(first: ""one"", second: ""two"")").WithLocation(6, 28));
+ }
+ else if (useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (5,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => A.GetFirst(second: 2, first: 1));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(second: 2, first: 1)").WithLocation(5, 28),
+ // (6,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => A.GetFirst(first: "one", second: "two"));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, @"A.GetFirst(first: ""one"", second: ""two"")").WithLocation(6, 28));
+ }
+ else
+ {
+ var verifier = CompileAndVerify(
+ comp,
+ expectedOutput: """
+ 1
+ one
+ """);
+ verifier.VerifyDiagnostics();
+ }
+
+ string sourceB3 = $$"""
+ class Program
+ {
+ static void Main()
+ {
+ Utils.Report(() => A.GetFirst(first: default, default));
+ Utils.Report(() => A.GetFirst(second: default, default));
+ Utils.Report(() => A.GetFirst(default, second: default));
+ Utils.Report(() => A.GetFirst(default, first: default));
+ }
+ }
+ """;
+ comp = CreateCompilation(
+ [sourceB3, GetUtilities(useExpression)],
+ references: [refA],
+ parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
+ options: TestOptions.ReleaseExe);
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (5,28): error CS0853: An expression tree may not contain a named argument specification
// Utils.Report(() => A.GetFirst(first: default, default));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(first: default, default)").WithLocation(7, 28),
- // (8,28): error CS0853: An expression tree may not contain a named argument specification
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(first: default, default)").WithLocation(5, 28),
+ // (6,28): error CS0853: An expression tree may not contain a named argument specification
// Utils.Report(() => A.GetFirst(second: default, default));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(second: default, default)").WithLocation(8, 28),
- // (9,28): error CS0853: An expression tree may not contain a named argument specification
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(second: default, default)").WithLocation(6, 28),
+ // (7,28): error CS0853: An expression tree may not contain a named argument specification
// Utils.Report(() => A.GetFirst(default, second: default));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(default, second: default)").WithLocation(9, 28),
- // (10,28): error CS0853: An expression tree may not contain a named argument specification
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(default, second: default)").WithLocation(7, 28),
+ // (8,28): error CS0853: An expression tree may not contain a named argument specification
// Utils.Report(() => A.GetFirst(default, first: default));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(default, first: default)").WithLocation(10, 28));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(default, first: default)").WithLocation(8, 28));
+ }
+ else if (useExpression)
+ {
+ comp.VerifyEmitDiagnostics();
}
else
{
var verifier = CompileAndVerify(
comp,
expectedOutput: """
- 1
- one
0
null
0
@@ -1482,7 +1458,7 @@ static void Main()
verifier.VerifyDiagnostics();
}
- string sourceB3 = $$"""
+ string sourceB4 = $$"""
class Program
{
static void Main()
@@ -1493,7 +1469,7 @@ static void Main()
}
""";
comp = CreateCompilation(
- [sourceB3, GetUtilities(useExpression)],
+ [sourceB4, GetUtilities(useExpression)],
references: [refA],
parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
options: TestOptions.ReleaseExe);
@@ -1506,6 +1482,312 @@ static void Main()
Diagnostic(ErrorCode.ERR_AmbigCall, "GetFirst").WithArguments("A.GetFirst(int, int)", "A.GetFirst(string, string)").WithLocation(6, 30));
}
+ [Theory]
+ [CombinatorialData]
+ public void NamedArgument_Constructor(
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ bool useExpression)
+ {
+ string sourceA = $$"""
+ public class A
+ {
+ public readonly string X;
+ public readonly int Y;
+ public A(string x, ref int y) { X = x; Y = y; }
+ public override string ToString() => $"({X}, {Y})";
+ }
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = comp.EmitToImageReference();
+
+ string sourceB1 = $$"""
+ class Program
+ {
+ static void Main()
+ {
+ int y = 1;
+ Utils.Report(() => new A(x: "one", ref y));
+ y = 2;
+ Utils.Report(() => new A("two", y: ref y));
+ y = 3;
+ Utils.Report(() => new A(x: "three", y: ref y));
+ }
+ }
+ """;
+ comp = CreateCompilation(
+ [sourceB1, GetUtilities(useExpression)],
+ references: [refA],
+ parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
+ options: TestOptions.ReleaseExe);
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (6,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => new A(x: "one", ref y));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, @"new A(x: ""one"", ref y)").WithLocation(6, 28),
+ // (8,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => new A("two", y: ref y));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, @"new A(""two"", y: ref y)").WithLocation(8, 28),
+ // (10,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => new A(x: "three", y: ref y));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, @"new A(x: ""three"", y: ref y)").WithLocation(10, 28));
+ }
+ else
+ {
+ var verifier = CompileAndVerify(
+ comp,
+ expectedOutput: """
+ (one, 1)
+ (two, 2)
+ (three, 3)
+ """);
+ verifier.VerifyDiagnostics();
+ }
+
+ string sourceB2 = $$"""
+ class Program
+ {
+ static void Main()
+ {
+ int y = 1;
+ Utils.Report(() => new A(y: ref y, x: "one"));
+ }
+ }
+ """;
+ comp = CreateCompilation(
+ [sourceB2, GetUtilities(useExpression)],
+ references: [refA],
+ parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
+ options: TestOptions.ReleaseExe);
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (6,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => new A(y: ref y, x: "one"));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, @"new A(y: ref y, x: ""one"")").WithLocation(6, 28));
+ }
+ else if (useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (6,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => new A(y: ref y, x: "one"));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, @"new A(y: ref y, x: ""one"")").WithLocation(6, 28));
+ }
+ else
+ {
+ var verifier = CompileAndVerify(
+ comp,
+ expectedOutput: """
+ (one, 1)
+ """);
+ verifier.VerifyDiagnostics();
+ }
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void NamedArgument_Indexer(
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ bool useExpression)
+ {
+ string sourceA = $$"""
+ public class A
+ {
+ public string this[int x, in string y] => y;
+ }
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = comp.EmitToImageReference();
+
+ string sourceB1 = $$"""
+ class Program
+ {
+ static void Main()
+ {
+ var a = new A();
+ string y = "one";
+ Utils.Report(() => a[x: 1, in y]);
+ Utils.Report(() => a[2, y: "two"]);
+ y = "three";
+ Utils.Report(() => a[x: 2, y: in y]);
+ }
+ }
+ """;
+ comp = CreateCompilation(
+ [sourceB1, GetUtilities(useExpression)],
+ references: [refA],
+ parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
+ options: TestOptions.ReleaseExe);
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (7,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => a[x: 1, in y]);
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "a[x: 1, in y]").WithLocation(7, 28),
+ // (8,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => a[2, y: "two"]);
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, @"a[2, y: ""two""]").WithLocation(8, 28),
+ // (10,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => a[x: 2, y: in y]);
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "a[x: 2, y: in y]").WithLocation(10, 28));
+ }
+ else
+ {
+ var verifier = CompileAndVerify(
+ comp,
+ expectedOutput: """
+ one
+ two
+ three
+ """);
+ verifier.VerifyDiagnostics();
+ }
+
+ string sourceB2 = $$"""
+ class Program
+ {
+ static void Main()
+ {
+ var a = new A();
+ string y = "two";
+ Utils.Report(() => a[y: "one", x: 1]);
+ Utils.Report(() => a[y: in y, x: 2]);
+ }
+ }
+ """;
+ comp = CreateCompilation(
+ [sourceB2, GetUtilities(useExpression)],
+ references: [refA],
+ parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
+ options: TestOptions.ReleaseExe);
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (7,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => a[y: "one", x: 1]);
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, @"a[y: ""one"", x: 1]").WithLocation(7, 28),
+ // (8,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => a[y: in y, x: 2]);
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "a[y: in y, x: 2]").WithLocation(8, 28));
+ }
+ else if (useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (7,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => a[y: "one", x: 1]);
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, @"a[y: ""one"", x: 1]").WithLocation(7, 28),
+ // (8,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => a[y: in y, x: 2]);
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "a[y: in y, x: 2]").WithLocation(8, 28));
+ }
+ else
+ {
+ var verifier = CompileAndVerify(
+ comp,
+ expectedOutput: """
+ one
+ two
+ """);
+ verifier.VerifyDiagnostics();
+ }
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void NamedArgument_Delegate(
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ bool useExpression)
+ {
+ string sourceA = $$"""
+ public delegate (T, U) D(T x, U y);
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = comp.EmitToImageReference();
+
+ string sourceB1 = $$"""
+ class Program
+ {
+ static void Main()
+ {
+ D d = F;
+ Utils.Report(() => d(x: 1, "one"));
+ Utils.Report(() => d(2, y: "two"));
+ Utils.Report(() => d(x: 3, y: "three"));
+ }
+ static (int, string) F(int i, string s) => (i, s);
+ }
+ """;
+ comp = CreateCompilation(
+ [sourceB1, GetUtilities(useExpression)],
+ references: [refA],
+ parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
+ options: TestOptions.ReleaseExe);
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (6,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => d(x: 1, "one"));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, @"d(x: 1, ""one"")").WithLocation(6, 28),
+ // (7,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => d(2, y: "two"));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, @"d(2, y: ""two"")").WithLocation(7, 28),
+ // (8,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => d(x: 3, y: "three"));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, @"d(x: 3, y: ""three"")").WithLocation(8, 28));
+ }
+ else
+ {
+ var verifier = CompileAndVerify(
+ comp,
+ expectedOutput: """
+ (1, one)
+ (2, two)
+ (3, three)
+ """);
+ verifier.VerifyDiagnostics();
+ }
+
+ string sourceB2 = $$"""
+ class Program
+ {
+ static void Main()
+ {
+ D d = F;
+ Utils.Report(() => d(y:"one", x:1));
+ }
+ static (int, string) F(int i, string s) => (i, s);
+ }
+ """;
+ comp = CreateCompilation(
+ [sourceB2, GetUtilities(useExpression)],
+ references: [refA],
+ parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
+ options: TestOptions.ReleaseExe);
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (6,28): error CS0853: An expression tree may not contain a named argument specification
+ // Utils.Report(() => d(y:"one", x:1));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, @"d(y:""one"", x:1)").WithLocation(6, 28));
+ }
+ else if (useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (6,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // Utils.Report(() => d(y:"one", x:1));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, @"d(y:""one"", x:1)").WithLocation(6, 28));
+ }
+ else
+ {
+ var verifier = CompileAndVerify(
+ comp,
+ expectedOutput: """
+ (1, one)
+ """);
+ verifier.VerifyDiagnostics();
+ }
+ }
+
[Theory]
[CombinatorialData]
public void NamedArgument_LocalFunction(
@@ -1552,9 +1834,9 @@ static void Main()
// (13,19): error CS8110: An expression tree may not contain a reference to a local function
// e = () => GetFirst(1, second: 2);
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsLocalFunction, "GetFirst(1, second: 2)").WithLocation(13, 19),
- // (14,19): error CS0853: An expression tree may not contain a named argument specification
+ // (14,19): error CS9300: An expression tree may not contain a named argument specification out of position
// e = () => GetFirst(second: 2, first: 1);
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "GetFirst(second: 2, first: 1)").WithLocation(14, 19));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "GetFirst(second: 2, first: 1)").WithLocation(14, 19));
}
}
}
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs
index 2542a831f9e0d..4b709d78e6602 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs
@@ -13082,8 +13082,10 @@ public static void Main(string[] args)
Diagnostic(ErrorCode.ERR_ArrayInitializerIncorrectLength, "{}").WithArguments("3").WithLocation(7, 31));
}
- [Fact]
- public void CS0853ERR_ExpressionTreeContainsNamedArgument01()
+ [Theory]
+ [InlineData(LanguageVersion.CSharp13)]
+ [InlineData(LanguageVersionFacts.CSharpNext)]
+ public void CS0853ERR_ExpressionTreeContainsNamedArgument01(LanguageVersion languageVersion)
{
var text = @"
using System.Linq.Expressions;
@@ -13103,16 +13105,25 @@ public static string Index(int minSessions = 0)
}
}
";
- CreateCompilationWithMscorlib40AndSystemCore(text).VerifyDiagnostics(
- // (10,40): error CS0853: An expression tree may not contain a named argument specification
- // Expression myET = x => Index(minSessions:5);
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "Index(minSessions:5)").WithLocation(10, 40)
- );
+ var comp = CreateCompilationWithMscorlib40AndSystemCore(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
+ if (languageVersion == LanguageVersion.CSharp13)
+ {
+ comp.VerifyDiagnostics(
+ // (10,40): error CS0853: An expression tree may not contain a named argument specification
+ // Expression myET = x => Index(minSessions:5);
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "Index(minSessions:5)").WithLocation(10, 40));
+ }
+ else
+ {
+ comp.VerifyDiagnostics();
+ }
}
[WorkItem(545063, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545063")]
- [Fact]
- public void CS0853ERR_ExpressionTreeContainsNamedArgument02()
+ [Theory]
+ [InlineData(LanguageVersion.CSharp13)]
+ [InlineData(LanguageVersionFacts.CSharpNext)]
+ public void CS0853ERR_ExpressionTreeContainsNamedArgument02(LanguageVersion languageVersion)
{
var text = @"
using System;
@@ -13127,11 +13138,18 @@ static void Main()
}
}
";
- CreateCompilationWithMscorlib40AndSystemCore(text).VerifyDiagnostics(
- // (10,41): error CS0853: An expression tree may not contain a named argument specification
- // Expression> f = () => new List { 1 } [index: 0];
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "new List { 1 } [index: 0]").WithLocation(10, 41)
- );
+ var comp = CreateCompilationWithMscorlib40AndSystemCore(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
+ if (languageVersion == LanguageVersion.CSharp13)
+ {
+ comp.VerifyDiagnostics(
+ // (10,41): error CS0853: An expression tree may not contain a named argument specification
+ // Expression> f = () => new List { 1 } [index: 0];
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "new List { 1 } [index: 0]").WithLocation(10, 41));
+ }
+ else
+ {
+ comp.VerifyDiagnostics();
+ }
}
[Theory]
@@ -13163,8 +13181,7 @@ public static string Index(int minSessions = 0)
comp.VerifyDiagnostics(
// (10,40): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
// Expression myET = x => Index();
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "Index()").WithLocation(10, 40)
- );
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "Index()").WithLocation(10, 40));
}
else
{
From 0aa49559f87f3f1f1c0c3ee574452c061bf07b7c Mon Sep 17 00:00:00 2001
From: Charles Stoner <10732005+cston@users.noreply.github.com>
Date: Mon, 7 Apr 2025 23:52:38 -0700
Subject: [PATCH 06/14] Update error code
---
.../CSharp/Portable/Errors/ErrorCode.cs | 2 +-
...xpressionOptionalAndNamedArgumentsTests.cs | 44 +++++++++----------
2 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
index 2c77ac7c38d92..e816b78cdc428 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@@ -2389,7 +2389,6 @@ internal enum ErrorCode
ERR_PPIgnoredFollowsToken = 9297,
ERR_PPIgnoredNeedsFileBasedProgram = 9298,
ERR_PPIgnoredFollowsIf = 9299,
- ERR_ExpressionTreeContainsNamedArgumentOutOfPosition = 9300,
ERR_RefExtensionParameterMustBeValueTypeOrConstrainedToOne = 9300,
ERR_InExtensionParameterMustBeValueType = 9301,
@@ -2398,6 +2397,7 @@ internal enum ErrorCode
ERR_InitInExtension = 9304,
ERR_ModifierOnUnnamedReceiverParameter = 9305,
ERR_ExtensionTypeNameDisallowed = 9306,
+ ERR_ExpressionTreeContainsNamedArgumentOutOfPosition = 9307,
// Note: you will need to do the following after adding errors:
// 1) Update ErrorFacts.IsBuildOnlyDiagnostic (src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs)
diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
index 110b4a93bd19e..f96b2b7fd36e7 100644
--- a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
@@ -739,7 +739,7 @@ static void Main()
else if (useExpression)
{
comp.VerifyEmitDiagnostics(
- // (5,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (5,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => A.GetFirst(second:2, first: 1));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(second:2, first: 1)").WithLocation(5, 28));
}
@@ -902,22 +902,22 @@ static void Main()
else if (useExpression)
{
comp.VerifyEmitDiagnostics(
- // (5,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (5,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => A.GetFirst(third:3, second: 2, first: 1));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(third:3, second: 2, first: 1)").WithLocation(5, 28),
- // (6,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (6,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => A.GetFirst(second:2, first: 1));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(second:2, first: 1)").WithLocation(6, 28),
- // (7,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (7,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => A.GetFirst(second:2, third: 3));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(second:2, third: 3)").WithLocation(7, 28),
- // (8,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (8,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => A.GetFirst(second:2));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(second:2)").WithLocation(8, 28),
- // (9,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (9,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => A.GetFirst(third:3, second: 2));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(third:3, second: 2)").WithLocation(9, 28),
- // (10,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (10,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => A.GetFirst(third:3));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(third:3)").WithLocation(10, 28));
}
@@ -1034,7 +1034,7 @@ static void Main()
else if (useExpression)
{
comp.VerifyEmitDiagnostics(
- // (5,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (5,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => A.GetFirstAndParamsLength(more: default, first: 1));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirstAndParamsLength(more: default, first: 1)").WithLocation(5, 28));
}
@@ -1234,25 +1234,25 @@ static void Main()
else if (useExpression)
{
comp.VerifyEmitDiagnostics(
- // (6,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (6,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => A.GetSecondAndParamsLength(first: 1, more: default, second: 2));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetSecondAndParamsLength(first: 1, more: default, second: 2)").WithLocation(6, 28),
- // (7,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (7,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => A.GetSecondAndParamsLength(first: 1, more: default));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetSecondAndParamsLength(first: 1, more: default)").WithLocation(7, 28),
- // (8,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (8,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => A.GetSecondAndParamsLength(second: 2));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetSecondAndParamsLength(second: 2)").WithLocation(8, 28),
- // (9,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (9,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => A.GetSecondAndParamsLength(second: 2, first: 1));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetSecondAndParamsLength(second: 2, first: 1)").WithLocation(9, 28),
- // (10,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (10,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => A.GetSecondAndParamsLength(second: 2, more: default));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetSecondAndParamsLength(second: 2, more: default)").WithLocation(10, 28),
- // (11,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (11,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => A.GetSecondAndParamsLength(more: new[] { 3, 4 }));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetSecondAndParamsLength(more: new[] { 3, 4 })").WithLocation(11, 28),
- // (12,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (12,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => A.GetSecondAndParamsLength(more: new[] { 3, 4 }, second: 2, first: 1));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetSecondAndParamsLength(more: new[] { 3, 4 }, second: 2, first: 1)").WithLocation(12, 28));
}
@@ -1390,10 +1390,10 @@ static void Main()
else if (useExpression)
{
comp.VerifyEmitDiagnostics(
- // (5,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (5,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => A.GetFirst(second: 2, first: 1));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(second: 2, first: 1)").WithLocation(5, 28),
- // (6,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (6,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => A.GetFirst(first: "one", second: "two"));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, @"A.GetFirst(first: ""one"", second: ""two"")").WithLocation(6, 28));
}
@@ -1569,7 +1569,7 @@ static void Main()
else if (useExpression)
{
comp.VerifyEmitDiagnostics(
- // (6,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (6,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => new A(y: ref y, x: "one"));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, @"new A(y: ref y, x: ""one"")").WithLocation(6, 28));
}
@@ -1673,10 +1673,10 @@ static void Main()
else if (useExpression)
{
comp.VerifyEmitDiagnostics(
- // (7,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (7,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => a[y: "one", x: 1]);
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, @"a[y: ""one"", x: 1]").WithLocation(7, 28),
- // (8,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (8,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => a[y: in y, x: 2]);
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "a[y: in y, x: 2]").WithLocation(8, 28));
}
@@ -1773,7 +1773,7 @@ static void Main()
else if (useExpression)
{
comp.VerifyEmitDiagnostics(
- // (6,28): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (6,28): error CS9307: An expression tree may not contain a named argument specification out of position
// Utils.Report(() => d(y:"one", x:1));
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, @"d(y:""one"", x:1)").WithLocation(6, 28));
}
@@ -1834,7 +1834,7 @@ static void Main()
// (13,19): error CS8110: An expression tree may not contain a reference to a local function
// e = () => GetFirst(1, second: 2);
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsLocalFunction, "GetFirst(1, second: 2)").WithLocation(13, 19),
- // (14,19): error CS9300: An expression tree may not contain a named argument specification out of position
+ // (14,19): error CS9307: An expression tree may not contain a named argument specification out of position
// e = () => GetFirst(second: 2, first: 1);
Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "GetFirst(second: 2, first: 1)").WithLocation(14, 19));
}
From abca25bd5c6e02212d43645ea1151fec5da15ee0 Mon Sep 17 00:00:00 2001
From: Charles Stoner <10732005+cston@users.noreply.github.com>
Date: Tue, 8 Apr 2025 00:07:40 -0700
Subject: [PATCH 07/14] IsBuildOnlyDiagnostic
---
src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
index aeba59ca89bc7..487389d7fa908 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
@@ -2513,6 +2513,7 @@ or ErrorCode.ERR_InstanceMemberWithUnnamedExtensionsParameter
or ErrorCode.ERR_InitInExtension
or ErrorCode.ERR_ModifierOnUnnamedReceiverParameter
or ErrorCode.ERR_ExtensionTypeNameDisallowed
+ or ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition
=> false,
};
#pragma warning restore CS8524 // The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value.
From 8bca3da413b730cd4091327d10bac90dffb0932f Mon Sep 17 00:00:00 2001
From: Charles Stoner <10732005+cston@users.noreply.github.com>
Date: Tue, 8 Apr 2025 09:05:41 -0700
Subject: [PATCH 08/14] Revert "Correct DefaultParameterValueAttribute in
diagnostic"
This reverts commit a8cbbce2998bbb8bc04213a3890b6903b8d66a21.
---
src/Compilers/CSharp/Portable/CSharpResources.resx | 2 +-
.../Symbols/Source/SourceComplexParameterSymbol.cs | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.cs.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.de.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.es.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.fr.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.it.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.ja.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.ko.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.pl.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.pt-BR.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.ru.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.tr.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf | 4 ++--
.../CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf | 4 ++--
.../CSharp/Test/Emit/Emit/OptionalArgumentsTests.cs | 10 +++++-----
.../CSharp/Test/Emit3/RefReadonlyParameterTests.cs | 10 +++++-----
.../CSharp/Test/Emit3/Semantics/ExtensionTests.cs | 2 +-
.../Test/Semantic/Semantics/NamedAndOptionalTests.cs | 4 ++--
.../Semantic/Semantics/NullableReferenceTypesTests.cs | 4 ++--
.../CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs | 2 +-
21 files changed, 45 insertions(+), 45 deletions(-)
diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index 6f9d49fe21624..f940c8ea7b476 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -4062,7 +4062,7 @@ You should consider suppressing the warning only if you're sure that you don't w
Named argument '{0}' is used out-of-position but is followed by an unnamed argument
- Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
Default parameter value for '{0}' must be a compile-time constant
diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceComplexParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceComplexParameterSymbol.cs
index 669a3bb286cdb..6f02978674217 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceComplexParameterSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceComplexParameterSymbol.cs
@@ -756,7 +756,7 @@ protected override void DecodeWellKnownAttributeImpl(ref DecodeWellKnownAttribut
if (HasDefaultArgumentSyntax)
{
- // error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
diagnostics.Add(ErrorCode.ERR_DefaultValueUsedWithAttributes, arguments.AttributeSyntaxOpt.Name.Location);
}
}
@@ -952,7 +952,7 @@ private ConstantValue DecodeDefaultParameterValueAttribute(CSharpAttributeData a
if (HasDefaultArgumentSyntax)
{
- // error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
if (diagnose)
{
diagnosticsOpt.Add(ErrorCode.ERR_DefaultValueUsedWithAttributes, node.Name.Location);
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
index 53bd10b2a1e20..6795aa712ec1d 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
@@ -11367,8 +11367,8 @@ Potlačení upozornění zvažte jenom v případě, když určitě nechcete če
- Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
- Nejde zadat výchozí hodnotu parametru v kombinaci s atributy DefaultParameterAttribute nebo OptionalAttribute.
+ Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ Nejde zadat výchozí hodnotu parametru v kombinaci s atributy DefaultParameterAttribute nebo OptionalAttribute.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
index 9162c1bf69556..fef82ba2dcc18 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
@@ -11367,8 +11367,8 @@ Sie sollten das Unterdrücken der Warnung nur in Betracht ziehen, wenn Sie siche
- Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
- Es kann kein Standardparameterwert in Verbindung mit "DefaultParameterAttribute" oder "OptionalAttribute" angegeben werden.
+ Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ Es kann kein Standardparameterwert in Verbindung mit "DefaultParameterAttribute" oder "OptionalAttribute" angegeben werden.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
index 8e61c791865e8..d39de65e1f75c 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
@@ -11367,8 +11367,8 @@ Considere la posibilidad de suprimir la advertencia solo si tiene la seguridad d
- Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
- No se puede especificar un valor de parámetro predeterminado junto con DefaultParameterAttribute u OptionalAttribute
+ Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ No se puede especificar un valor de parámetro predeterminado junto con DefaultParameterAttribute u OptionalAttribute
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
index 7fdb310fb227c..a7c0e82371b41 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
@@ -11367,8 +11367,8 @@ Supprimez l'avertissement seulement si vous êtes sûr de ne pas vouloir attendr
- Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
- Impossible de spécifier une valeur de paramètre par défaut conjointement à DefaultParameterAttribute ou OptionalAttribute
+ Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ Impossible de spécifier une valeur de paramètre par défaut conjointement à DefaultParameterAttribute ou OptionalAttribute
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
index c3eb3a4c981d0..3c9c4b638996c 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
@@ -11367,8 +11367,8 @@ Come procedura consigliata, è consigliabile attendere sempre la chiamata.
- Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
- Impossibile specificare un valore di parametro predefinito insieme a DefaultParameterAttribute o OptionalAttribute
+ Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ Impossibile specificare un valore di parametro predefinito insieme a DefaultParameterAttribute o OptionalAttribute
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
index a6fd514f07316..89652d71d304c 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
@@ -11367,8 +11367,8 @@ You should consider suppressing the warning only if you're sure that you don't w
- Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
- DefaultParameterAttribute または OptionalAttribute と共に既定パラメーター値を指定することはできません
+ Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ DefaultParameterAttribute または OptionalAttribute と共に既定パラメーター値を指定することはできません
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
index 3336233b38845..2931f97754d3c 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
@@ -11367,8 +11367,8 @@ You should consider suppressing the warning only if you're sure that you don't w
- Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
- DefaultParameterAttribute 또는 OptionalAttribute와 함께 기본 매개 변수 값을 지정할 수 없습니다.
+ Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ DefaultParameterAttribute 또는 OptionalAttribute와 함께 기본 매개 변수 값을 지정할 수 없습니다.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
index 7164292799fcb..9aa2a31cfa12c 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
@@ -11367,8 +11367,8 @@ Pominięcie ostrzeżenia należy wziąć pod uwagę tylko w sytuacji, gdy na pew
- Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
- Nie można określić wartości domyślnej parametru w połączeniu z klasami DefaultParameterAttribute lub OptionalAttribute
+ Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ Nie można określić wartości domyślnej parametru w połączeniu z klasami DefaultParameterAttribute lub OptionalAttribute
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
index 9a198e4020104..327398efa7c86 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
@@ -11367,8 +11367,8 @@ Você pode suprimir o aviso se tiver certeza de que não vai querer aguardar a c
- Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
- Não é possível especificar um valor de parâmetro padrão junto com DefaultParameterAttribute ou OptionalAttribute
+ Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ Não é possível especificar um valor de parâmetro padrão junto com DefaultParameterAttribute ou OptionalAttribute
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
index e94baafb13fce..8e43ce0310444 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
@@ -11368,8 +11368,8 @@ You should consider suppressing the warning only if you're sure that you don't w
- Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
- Не удалось указать значение параметра по умолчанию вместе с DefaultParameterAttribute или OptionalAttribute.
+ Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ Не удалось указать значение параметра по умолчанию вместе с DefaultParameterAttribute или OptionalAttribute.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
index b02b11ead4468..70a0bc99f2505 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
@@ -11367,8 +11367,8 @@ Yalnızca asenkron çağrının tamamlanmasını beklemek istemediğinizden ve
- Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
- DefaultParameterAttribute veya OptionalAttribute ile birlikte varsayılan parametre değeri belirtilemez
+ Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ DefaultParameterAttribute veya OptionalAttribute ile birlikte varsayılan parametre değeri belirtilemez
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
index 746f8c3de9623..741909a05e9bc 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
@@ -11367,8 +11367,8 @@ You should consider suppressing the warning only if you're sure that you don't w
- Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
- 不能同时指定默认参数值与 DefaultParameterAttribute 或 OptionalAttribute
+ Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ 不能同时指定默认参数值与 DefaultParameterAttribute 或 OptionalAttribute
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
index 12c695a330ffc..72d9bb03d5892 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
@@ -11367,8 +11367,8 @@ You should consider suppressing the warning only if you're sure that you don't w
- Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
- 不能連同 DefaultParameterAttribute 或 OptionalAttribute 一起指定預設參數值
+ Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
+ 不能連同 DefaultParameterAttribute 或 OptionalAttribute 一起指定預設參數值
diff --git a/src/Compilers/CSharp/Test/Emit/Emit/OptionalArgumentsTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/OptionalArgumentsTests.cs
index 876153b624004..cc001016cb53b 100644
--- a/src/Compilers/CSharp/Test/Emit/Emit/OptionalArgumentsTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/Emit/OptionalArgumentsTests.cs
@@ -255,10 +255,10 @@ interface I
delegate void D([DecimalConstant(0, 0, 0, 0, 3)]decimal b = 4);
";
CreateCompilation(source).VerifyDiagnostics(
- // (5,14): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // (5,14): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
// void F1([DefaultParameterValue(1)]int o = 2);
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(5, 14),
- // (6,14): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // (6,14): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
// void F2([DefaultParameterValue(1)]decimal o = 2);
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(6, 14),
// (6,51): error CS8017: The parameter has multiple distinct default values.
@@ -267,7 +267,7 @@ interface I
// (7,57): error CS8017: The parameter has multiple distinct default values.
// void F4([DecimalConstant(0, 0, 0, 0, 1)]decimal o = 2);
Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "2").WithLocation(7, 57),
- // (8,35): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // (8,35): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
// void F6([DateTimeConstant(1), DefaultParameterValue(1), DecimalConstant(0, 0, 0, 0, 1)]int o = 1);
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(8, 35),
// (8,61): error CS8017: The parameter has multiple distinct default values.
@@ -279,13 +279,13 @@ interface I
// (9,35): error CS8017: The parameter has multiple distinct default values.
// void F7([DateTimeConstant(2), DecimalConstant(0, 0, 0, 0, 2), DefaultParameterValue(2)]decimal o = 2);
Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "DecimalConstant(0, 0, 0, 0, 2)").WithLocation(9, 35),
- // (9,67): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // (9,67): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
// void F7([DateTimeConstant(2), DecimalConstant(0, 0, 0, 0, 2), DefaultParameterValue(2)]decimal o = 2);
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(9, 67),
// (9,104): error CS8017: The parameter has multiple distinct default values.
// void F7([DateTimeConstant(2), DecimalConstant(0, 0, 0, 0, 2), DefaultParameterValue(2)]decimal o = 2);
Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "2").WithLocation(9, 104),
- // (10,25): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // (10,25): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
// object this[int a, [DefaultParameterValue(1)]int o = 2] { get; set; }
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(10, 25),
// (10,58): error CS8017: The parameter has multiple distinct default values.
diff --git a/src/Compilers/CSharp/Test/Emit3/RefReadonlyParameterTests.cs b/src/Compilers/CSharp/Test/Emit3/RefReadonlyParameterTests.cs
index 7359081866010..12482bd5997b1 100644
--- a/src/Compilers/CSharp/Test/Emit3/RefReadonlyParameterTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/RefReadonlyParameterTests.cs
@@ -4621,7 +4621,7 @@ class C
}
""";
CreateCompilation(source).VerifyDiagnostics(
- // (4,20): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // (4,20): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
// static void M([DefaultParameterValue(1)] ref readonly int i = 1) => throw null;
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(4, 20),
// (4,67): warning CS9200: A default value is specified for 'ref readonly' parameter 'i', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
@@ -4643,7 +4643,7 @@ class C
}
""";
CreateCompilation(source).VerifyDiagnostics(
- // (4,20): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // (4,20): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
// static void M([Optional] ref readonly int i = 1) => throw null;
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "Optional").WithLocation(4, 20),
// (4,51): warning CS9200: A default value is specified for 'ref readonly' parameter 'i', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
@@ -4662,10 +4662,10 @@ class C
}
""";
CreateCompilation(source).VerifyDiagnostics(
- // (4,20): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // (4,20): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
// static void M([Optional, DefaultParameterValue(1)] ref readonly int i = 1) => throw null;
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "Optional").WithLocation(4, 20),
- // (4,30): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // (4,30): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
// static void M([Optional, DefaultParameterValue(1)] ref readonly int i = 1) => throw null;
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(4, 30),
// (4,77): warning CS9200: A default value is specified for 'ref readonly' parameter 'i', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
@@ -4797,7 +4797,7 @@ static void Main()
}
""";
CreateCompilation(source).VerifyDiagnostics(
- // (6,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // (6,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
// static void M2([Optional, DecimalConstant(1, 0, 0u, 0u, 11u)] ref readonly decimal d = 1.1m) => throw null;
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "Optional").WithLocation(6, 21),
// (6,92): warning CS9200: A default value is specified for 'ref readonly' parameter 'd', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs
index 9e1106e0371e6..8d7496e27f055 100644
--- a/src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs
@@ -2522,7 +2522,7 @@ public static class Extensions
// (3,15): error CS9284: The receiver parameter of an extension cannot have a default value
// extension([System.Runtime.InteropServices.DefaultParameterValue(1)] int o = 2) { }
Diagnostic(ErrorCode.ERR_ExtensionParameterDisallowsDefaultValue, "[System.Runtime.InteropServices.DefaultParameterValue(1)] int o = 2").WithLocation(3, 15),
- // (3,16): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // (3,16): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
// extension([System.Runtime.InteropServices.DefaultParameterValue(1)] int o = 2) { }
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "System.Runtime.InteropServices.DefaultParameterValue").WithLocation(3, 16));
}
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NamedAndOptionalTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NamedAndOptionalTests.cs
index ce2f5d8141272..10ebc0f4cb410 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/NamedAndOptionalTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NamedAndOptionalTests.cs
@@ -962,13 +962,13 @@ public static int Main(){
}
";
CreateCompilation(source).VerifyDiagnostics(
- // (9,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // (9,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
// public int Bar([DefaultParameterValue(1)]int i = 2) {
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(9, 21),
// (9,54): error CS8017: The parameter has multiple distinct default values.
// public int Bar([DefaultParameterValue(1)]int i = 2) {
Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "2").WithLocation(9, 54),
- // (5,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // (5,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
// public int Goo([Optional]object i = null) {
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "Optional").WithLocation(5, 21)
);
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
index cccbae0f0badc..7315a2e033e0d 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
@@ -82159,10 +82159,10 @@ public void M3([Optional, DefaultParameterValue(null)] object obj = null)
// (9,31): error CS8017: The parameter has multiple distinct default values.
// public void M2([Optional, DefaultParameterValue(default)] object obj)
Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "DefaultParameterValue(default)").WithLocation(9, 31),
- // (13,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // (13,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
// public void M3([Optional, DefaultParameterValue(null)] object obj = null)
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "Optional").WithLocation(13, 21),
- // (13,31): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // (13,31): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
// public void M3([Optional, DefaultParameterValue(null)] object obj = null)
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(13, 31),
// (13,73): warning CS8625: Cannot convert null literal to non-nullable reference type.
diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs
index 7780a6bdfe315..35eeaa428bee8 100644
--- a/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs
+++ b/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs
@@ -16148,7 +16148,7 @@ public static void Main() { }
}
";
CreateCompilation(text).VerifyDiagnostics(
- // (5,22): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterValueAttribute or OptionalAttribute
+ // (5,22): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
// public void goo([OptionalAttribute]int p = 1)
Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "OptionalAttribute")
);
From 17e91c5bb70ded5309aea75cd5e1412bd7b44f69 Mon Sep 17 00:00:00 2001
From: Charles Stoner <10732005+cston@users.noreply.github.com>
Date: Tue, 8 Apr 2025 12:01:53 -0700
Subject: [PATCH 09/14] Address feedback
---
.../DiagnosticsPass_ExpressionTrees.cs | 2 +-
.../Emit/CodeGen/CodeGenExprLambdaTests.cs | 8 +-
...xpressionOptionalAndNamedArgumentsTests.cs | 106 ++++++++++++++----
.../Semantic/Semantics/SemanticErrorTests.cs | 41 +++----
.../Test/Utilities/CSharp/CSharpTestBase.cs | 2 +
5 files changed, 111 insertions(+), 48 deletions(-)
diff --git a/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs b/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs
index ad3d0261b8307..7eb5688d29da3 100644
--- a/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/DiagnosticsPass_ExpressionTrees.cs
@@ -340,9 +340,9 @@ private void VisitCall(
Error(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, node);
}
else if (!argumentNamesOpt.IsDefaultOrEmpty &&
- _compilation.IsFeatureEnabled(MessageID.IDS_FeatureExpressionOptionalAndNamedArguments) &&
hasNamedArgumentOutOfOrder(argsToParamsOpt))
{
+ Debug.Assert(_compilation.IsFeatureEnabled(MessageID.IDS_FeatureExpressionOptionalAndNamedArguments));
Error(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, node);
}
else if (IsComCallWithRefOmitted(method, arguments, argumentRefKindsOpt))
diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenExprLambdaTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenExprLambdaTests.cs
index 8d381df612ae4..a79f04945d6b0 100644
--- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenExprLambdaTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenExprLambdaTests.cs
@@ -2596,8 +2596,7 @@ static void Main()
}
[Theory]
- [InlineData(LanguageVersion.CSharp13)]
- [InlineData(LanguageVersionFacts.CSharpNext)]
+ [MemberData(nameof(LanguageVersions13AndNewer))]
public void MethodCallWithParams3(LanguageVersion languageVersion)
{
var text =
@@ -2614,7 +2613,7 @@ static void Main()
Console.WriteLine(testExpr);
}
}";
- var comp = CreateCompilationWithMscorlib40AndSystemCore(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
+ var comp = CreateCompilationWithMscorlib40AndSystemCore(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseExe);
if (languageVersion == LanguageVersion.CSharp13)
{
comp.VerifyDiagnostics(
@@ -2625,7 +2624,8 @@ static void Main()
}
else
{
- comp.VerifyDiagnostics();
+ var verifier = CompileAndVerify(comp, expectedOutput: "() => ModAdd2(3, 4, new [] {})");
+ verifier.VerifyDiagnostics();
}
}
diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
index f96b2b7fd36e7..1e9ca55554146 100644
--- a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
@@ -50,12 +50,11 @@ public static T Run(Func f)
[Theory]
[CombinatorialData]
public void OptionalParameter_01(
- [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
- bool useIn,
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ [CombinatorialValues("", "in", "ref readonly")] string refKind,
bool useExpression,
bool useCompilationReference)
{
- string refKind = useIn ? "in" : "";
string sourceA = $$"""
public static class A
{
@@ -106,18 +105,27 @@ static void Main()
null
S
""");
- verifier.VerifyDiagnostics();
+ if (useCompilationReference && refKind == "ref readonly")
+ {
+ verifier.VerifyDiagnostics(
+ // (3,52): warning CS9200: A default value is specified for 'ref readonly' parameter 't', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
+ // public static T GetValue(ref readonly T t = default) => t;
+ Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "default").WithArguments("t").WithLocation(3, 52));
+ }
+ else
+ {
+ verifier.VerifyDiagnostics();
+ }
}
}
[Theory]
[CombinatorialData]
public void OptionalParameter_02(
- bool useIn,
+ [CombinatorialValues("", "in", "ref readonly")] string refKind,
bool useExpression,
bool useCompilationReference)
{
- string refKind = useIn ? "in" : "";
string sourceA = $$"""
public static class A
{
@@ -148,17 +156,32 @@ static void Main()
default
null
""");
- verifier.VerifyDiagnostics();
+ if (useCompilationReference && refKind == "ref readonly")
+ {
+ verifier.VerifyDiagnostics(
+ // (3,56): warning CS9200: A default value is specified for 'ref readonly' parameter 'i', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
+ // public static int GetIntValue(ref readonly int i = 10) => i;
+ Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "10").WithArguments("i").WithLocation(3, 56),
+ // (4,65): warning CS9200: A default value is specified for 'ref readonly' parameter 's', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
+ // public static string GetStringValue(ref readonly string s = "default") => s;
+ Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, @"""default""").WithArguments("s").WithLocation(4, 65),
+ // (5,65): warning CS9200: A default value is specified for 'ref readonly' parameter 'o', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
+ // public static object GetObjectValue(ref readonly object o = null) => o;
+ Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "null").WithArguments("o").WithLocation(5, 65));
+ }
+ else
+ {
+ verifier.VerifyDiagnostics();
+ }
}
[Theory]
[CombinatorialData]
public void OptionalParameter_AndParams(
- bool useIn,
+ [CombinatorialValues("", "in", "ref readonly")] string refKind,
bool useExpression,
bool useCompilationReference)
{
- string refKind = useIn ? "in" : "";
string sourceA = $$"""
public static class A
{
@@ -188,13 +211,48 @@ static void Main()
0
3
""");
- verifier.VerifyDiagnostics();
+ if (refKind == "ref readonly")
+ {
+ if (useCompilationReference)
+ {
+ verifier.VerifyDiagnostics(
+ // (3,70): warning CS9200: A default value is specified for 'ref readonly' parameter 'y', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
+ // public static T GetValue(ref readonly T x, ref readonly T y = default, params T[] args) => y;
+ Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "default").WithArguments("y").WithLocation(3, 70),
+ // (8,44): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter
+ // Utils.Report(() => A.GetValue(1));
+ Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "1").WithArguments("1").WithLocation(8, 44),
+ // (9,44): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter
+ // Utils.Report(() => A.GetValue(2, 3, 4));
+ Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "2").WithArguments("1").WithLocation(9, 44),
+ // (9,47): warning CS9193: Argument 2 should be a variable because it is passed to a 'ref readonly' parameter
+ // Utils.Report(() => A.GetValue(2, 3, 4));
+ Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "3").WithArguments("2").WithLocation(9, 47));
+ }
+ else
+ {
+ verifier.VerifyDiagnostics(
+ // (8,44): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter
+ // Utils.Report(() => A.GetValue(1));
+ Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "1").WithArguments("1").WithLocation(8, 44),
+ // (9,44): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter
+ // Utils.Report(() => A.GetValue(2, 3, 4));
+ Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "2").WithArguments("1").WithLocation(9, 44),
+ // (9,47): warning CS9193: Argument 2 should be a variable because it is passed to a 'ref readonly' parameter
+ // Utils.Report(() => A.GetValue(2, 3, 4));
+ Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "3").WithArguments("2").WithLocation(9, 47));
+ }
+ }
+ else
+ {
+ verifier.VerifyDiagnostics();
+ }
}
[Theory]
[CombinatorialData]
public void OptionalParameter_Constructor(
- [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
bool useExpression)
{
string sourceA = $$"""
@@ -249,7 +307,7 @@ static void Main()
[Theory]
[CombinatorialData]
public void OptionalParameter_Indexer(
- [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
bool useExpression)
{
string sourceA = $$"""
@@ -299,7 +357,7 @@ static void Main()
[Theory]
[CombinatorialData]
public void OptionalParameter_Delegate(
- [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
bool useExpression)
{
string sourceA = $$"""
@@ -347,7 +405,7 @@ static void Main()
[Theory]
[CombinatorialData]
public void OptionalParameter_CollectionInitializer(
- [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
bool useExpression,
bool useIn)
{
@@ -411,7 +469,7 @@ static void Main()
[Theory]
[CombinatorialData]
public void OptionalParameter_LocalFunction(
- [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion)
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion)
{
string source = """
using System;
@@ -661,7 +719,7 @@ static void Main()
[Theory]
[CombinatorialData]
public void NamedArgument_01(
- [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
bool useExpression,
bool useCompilationReference)
{
@@ -780,7 +838,7 @@ static void Main()
[Theory]
[CombinatorialData]
public void NamedArgument_02(
- [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
bool useExpression,
bool useCompilationReference)
{
@@ -941,7 +999,7 @@ static void Main()
[Theory]
[CombinatorialData]
public void NamedArgument_03(
- [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
bool useExpression,
bool useCompilationReference)
{
@@ -1083,7 +1141,7 @@ static void Main()
[Theory]
[CombinatorialData]
public void NamedArgument_04(
- [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
bool useExpression,
bool useCompilationReference)
{
@@ -1312,7 +1370,7 @@ static void Main()
[Theory]
[CombinatorialData]
public void NamedArgument_OverloadsDifferentOrder(
- [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
bool useExpression,
bool useCompilationReference)
{
@@ -1485,7 +1543,7 @@ static void Main()
[Theory]
[CombinatorialData]
public void NamedArgument_Constructor(
- [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
bool useExpression)
{
string sourceA = $$"""
@@ -1587,7 +1645,7 @@ static void Main()
[Theory]
[CombinatorialData]
public void NamedArgument_Indexer(
- [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
bool useExpression)
{
string sourceA = $$"""
@@ -1695,7 +1753,7 @@ static void Main()
[Theory]
[CombinatorialData]
public void NamedArgument_Delegate(
- [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
bool useExpression)
{
string sourceA = $$"""
@@ -1791,7 +1849,7 @@ static void Main()
[Theory]
[CombinatorialData]
public void NamedArgument_LocalFunction(
- [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion)
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion)
{
string source = """
using System;
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs
index 4b709d78e6602..9444f9be5f192 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs
@@ -13083,8 +13083,7 @@ public static void Main(string[] args)
}
[Theory]
- [InlineData(LanguageVersion.CSharp13)]
- [InlineData(LanguageVersionFacts.CSharpNext)]
+ [MemberData(nameof(LanguageVersions13AndNewer))]
public void CS0853ERR_ExpressionTreeContainsNamedArgument01(LanguageVersion languageVersion)
{
var text = @"
@@ -13097,6 +13096,7 @@ class Program
static void Main(string[] args)
{
Expression myET = x => Index(minSessions:5);
+ System.Console.WriteLine(myET);
}
public static string Index(int minSessions = 0)
{
@@ -13105,7 +13105,7 @@ public static string Index(int minSessions = 0)
}
}
";
- var comp = CreateCompilationWithMscorlib40AndSystemCore(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
+ var comp = CreateCompilationWithMscorlib40AndSystemCore(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseExe);
if (languageVersion == LanguageVersion.CSharp13)
{
comp.VerifyDiagnostics(
@@ -13115,14 +13115,14 @@ public static string Index(int minSessions = 0)
}
else
{
- comp.VerifyDiagnostics();
+ var verifier = CompileAndVerify(comp, expectedOutput: "x => Index(5)");
+ verifier.VerifyDiagnostics();
}
}
[WorkItem(545063, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545063")]
[Theory]
- [InlineData(LanguageVersion.CSharp13)]
- [InlineData(LanguageVersionFacts.CSharpNext)]
+ [MemberData(nameof(LanguageVersions13AndNewer))]
public void CS0853ERR_ExpressionTreeContainsNamedArgument02(LanguageVersion languageVersion)
{
var text = @"
@@ -13135,10 +13135,11 @@ class A
static void Main()
{
Expression> f = () => new List { 1 } [index: 0];
+ Console.WriteLine(f);
}
}
";
- var comp = CreateCompilationWithMscorlib40AndSystemCore(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
+ var comp = CreateCompilationWithMscorlib40AndSystemCore(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseExe);
if (languageVersion == LanguageVersion.CSharp13)
{
comp.VerifyDiagnostics(
@@ -13148,13 +13149,13 @@ static void Main()
}
else
{
- comp.VerifyDiagnostics();
+ var verifier = CompileAndVerify(comp, expectedOutput: "() => new List`1() {Void Add(Int32)(1)}.get_Item(0)");
+ verifier.VerifyDiagnostics();
}
}
[Theory]
- [InlineData(LanguageVersion.CSharp13)]
- [InlineData(LanguageVersionFacts.CSharpNext)]
+ [MemberData(nameof(LanguageVersions13AndNewer))]
public void CS0854ERR_ExpressionTreeContainsOptionalArgument01(LanguageVersion languageVersion)
{
var text = @"
@@ -13167,6 +13168,7 @@ class Program
static void Main(string[] args)
{
Expression myET = x => Index();
+ System.Console.WriteLine(myET);
}
public static string Index(int minSessions = 0)
{
@@ -13175,7 +13177,7 @@ public static string Index(int minSessions = 0)
}
}
";
- var comp = CreateCompilationWithMscorlib40AndSystemCore(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
+ var comp = CreateCompilationWithMscorlib40AndSystemCore(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseExe);
if (languageVersion == LanguageVersion.CSharp13)
{
comp.VerifyDiagnostics(
@@ -13185,13 +13187,13 @@ public static string Index(int minSessions = 0)
}
else
{
- comp.VerifyDiagnostics();
+ var verifier = CompileAndVerify(comp, expectedOutput: "x => Index(0)");
+ verifier.VerifyDiagnostics();
}
}
[Theory]
- [InlineData(LanguageVersion.CSharp13)]
- [InlineData(LanguageVersionFacts.CSharpNext)]
+ [MemberData(nameof(LanguageVersions13AndNewer))]
public void CS0854ERR_ExpressionTreeContainsOptionalArgument02(LanguageVersion languageVersion)
{
var text =
@@ -13253,8 +13255,7 @@ static void M(A a, B b)
}
[Theory]
- [InlineData(LanguageVersion.CSharp13)]
- [InlineData(LanguageVersionFacts.CSharpNext)]
+ [MemberData(nameof(LanguageVersions13AndNewer))]
public void CS0854ERR_ExpressionTreeContainsOptionalArgument03(LanguageVersion languageVersion)
{
var text =
@@ -13273,12 +13274,13 @@ public IEnumerator GetEnumerator()
}
public class C {
- public void M() {
+ static void Main() {
Expression> expr =
() => new Collection { 1 }; // 1
+ Console.WriteLine(expr);
}
}";
- var comp = CreateCompilation(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion));
+ var comp = CreateCompilation(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseExe);
if (languageVersion == LanguageVersion.CSharp13)
{
comp.VerifyDiagnostics(
@@ -13288,7 +13290,8 @@ public void M() {
}
else
{
- comp.VerifyDiagnostics();
+ var verifier = CompileAndVerify(comp, expectedOutput: "() => new Collection() {Void Add(Int32, Int32)(1, 0)}");
+ verifier.VerifyDiagnostics();
}
}
diff --git a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs
index cabe8fa772230..724caf2c1654d 100644
--- a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs
+++ b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs
@@ -37,6 +37,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Test.Utilities
{
public abstract class CSharpTestBase : CommonTestBase
{
+ public static readonly TheoryData LanguageVersions13AndNewer = new([LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext]);
+
protected static readonly string NullableAttributeDefinition = @"
namespace System.Runtime.CompilerServices
{
From 4edfbb67091dcc1f4d5e792ce904b21f5b01a893 Mon Sep 17 00:00:00 2001
From: Charles Stoner <10732005+cston@users.noreply.github.com>
Date: Tue, 8 Apr 2025 20:07:55 -0700
Subject: [PATCH 10/14] Report Expression shape
---
...xpressionOptionalAndNamedArgumentsTests.cs | 285 ++++++++++--------
1 file changed, 157 insertions(+), 128 deletions(-)
diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
index 1e9ca55554146..dacc153a746e5 100644
--- a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable disable
+
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Xunit;
@@ -21,7 +23,7 @@ public static class Utils
public static void Report(Expression> f)
{
object value = Run(f);
- Console.WriteLine(value is null ? "null" : value.ToString());
+ Console.WriteLine("{0}: {1}", f, value is null ? "null" : value.ToString());
}
public static T Run(Expression> e)
{
@@ -37,7 +39,7 @@ public static class Utils
public static void Report(Func f)
{
object value = Run(f);
- Console.WriteLine(value is null ? "null" : value.ToString());
+ Console.WriteLine("--: {0}", value is null ? "null" : value.ToString());
}
public static T Run(Func f)
{
@@ -47,6 +49,30 @@ public static T Run(Func f)
""";
}
+ private static string IncludeExpression(bool useExpression, string expectedOutput)
+ {
+ if (useExpression)
+ {
+ return expectedOutput;
+ }
+ var builder = new System.Text.StringBuilder();
+ using var reader = new System.IO.StringReader(expectedOutput);
+ while (reader.ReadLine() is { } line)
+ {
+ int index = line.IndexOf(':');
+ if (index >= 0)
+ {
+ builder.Append("--");
+ builder.AppendLine(line.Substring(index));
+ }
+ else
+ {
+ builder.AppendLine(line);
+ }
+ }
+ return builder.ToString();
+ }
+
[Theory]
[CombinatorialData]
public void OptionalParameter_01(
@@ -100,11 +126,11 @@ static void Main()
{
var verifier = CompileAndVerify(
comp,
- expectedOutput: """
- 0
- null
- S
- """);
+ expectedOutput: IncludeExpression(useExpression, """
+ () => GetValue(0): 0
+ () => GetValue(null): null
+ () => GetValue(value(S)): S
+ """));
if (useCompilationReference && refKind == "ref readonly")
{
verifier.VerifyDiagnostics(
@@ -151,11 +177,11 @@ static void Main()
var verifier = CompileAndVerify(
[sourceB, GetUtilities(useExpression)],
references: [refA],
- expectedOutput: """
- 10
- default
- null
- """);
+ expectedOutput: IncludeExpression(useExpression, """
+ () => GetIntValue(10): 10
+ () => GetStringValue("default"): default
+ () => GetObjectValue(null): null
+ """));
if (useCompilationReference && refKind == "ref readonly")
{
verifier.VerifyDiagnostics(
@@ -207,10 +233,10 @@ static void Main()
var verifier = CompileAndVerify(
[sourceB, GetUtilities(useExpression)],
references: [refA],
- expectedOutput: """
- 0
- 3
- """);
+ expectedOutput: IncludeExpression(useExpression, """
+ () => GetValue(1, 0, new [] {}): 0
+ () => GetValue(2, 3, new [] {4}): 3
+ """));
if (refKind == "ref readonly")
{
if (useCompilationReference)
@@ -296,10 +322,10 @@ static void Main()
{
var verifier = CompileAndVerify(
comp,
- expectedOutput: """
- (str, 10)
- (default, 10)
- """);
+ expectedOutput: IncludeExpression(useExpression, """
+ () => new A("str", 10): (str, 10)
+ () => new A("default", 10): (default, 10)
+ """));
verifier.VerifyDiagnostics();
}
}
@@ -346,10 +372,10 @@ static void Main()
{
var verifier = CompileAndVerify(
comp,
- expectedOutput: """
- 2
- 10
- """);
+ expectedOutput: IncludeExpression(useExpression, """
+ () => value(Program+<>c__DisplayClass0_0).a.get_Item(1, 2): 2
+ () => value(Program+<>c__DisplayClass0_0).a.get_Item(3, 10): 10
+ """));
verifier.VerifyDiagnostics();
}
}
@@ -394,10 +420,10 @@ static void Main()
{
var verifier = CompileAndVerify(
comp,
- expectedOutput: """
- 2
- 10
- """);
+ expectedOutput: IncludeExpression(useExpression, """
+ () => Invoke(value(Program+<>c__DisplayClass0_0).d, 1, 2): 2
+ () => Invoke(value(Program+<>c__DisplayClass0_0).d, 3, 10): 10
+ """));
verifier.VerifyDiagnostics();
}
}
@@ -461,7 +487,9 @@ static void Main()
{
var verifier = CompileAndVerify(
comp,
- expectedOutput: "(one, 1), (two, 0)");
+ expectedOutput: IncludeExpression(useExpression, """
+ () => new MyCollection`2() {Void Add(System.String, Int32)("one", 1), Void Add(System.String, Int32)("two", 0)}: (one, 1), (two, 0)
+ """));
verifier.VerifyDiagnostics();
}
}
@@ -538,10 +566,10 @@ static void Main()
var verifier = CompileAndVerify(
[sourceB, GetUtilities(useExpression)],
references: [refA],
- expectedOutput: """
- 200
- 100
- """);
+ expectedOutput: IncludeExpression(useExpression, """
+ () => GetValue(200): 200
+ () => GetValue(100): 100
+ """));
verifier.VerifyDiagnostics();
}
@@ -577,10 +605,10 @@ static void Main()
var verifier = CompileAndVerify(
[sourceB, GetUtilities(useExpression)],
references: [refA],
- expectedOutput: """
- 200
- 100
- """);
+ expectedOutput: IncludeExpression(useExpression, """
+ () => GetValue(new DateTime(200)).Ticks: 200
+ () => GetValue(new DateTime(100)).Ticks: 100
+ """));
verifier.VerifyDiagnostics();
}
@@ -656,12 +684,13 @@ static void Main()
options: TestOptions.ReleaseExe);
if (includeOptional)
{
+ string parameterValue = includeDefaultParameterValue ? "100" : "0";
var verifier = CompileAndVerify(
comp,
- expectedOutput: $$"""
- 200
- {{(includeDefaultParameterValue ? "100" : "0")}}
- """);
+ expectedOutput: IncludeExpression(useExpression, $$"""
+ () => GetValue(200): 200
+ () => GetValue({{parameterValue}}): {{parameterValue}}
+ """));
verifier.VerifyDiagnostics();
}
else
@@ -709,10 +738,10 @@ static void Main()
var verifier = CompileAndVerify(
[sourceB, GetUtilities(useExpression)],
references: [refA],
- expectedOutput: """
- 3
- 0
- """);
+ expectedOutput: IncludeExpression(useExpression, """
+ () => GetValue(new [] {Convert(1, Object), Convert(2, Object), Convert(3, Object)}): 3
+ () => GetValue(new [] {}): 0
+ """));
verifier.VerifyDiagnostics();
}
@@ -765,11 +794,11 @@ static void Main()
{
var verifier = CompileAndVerify(
comp,
- expectedOutput: """
- 1
- 1
- 1
- """);
+ expectedOutput: IncludeExpression(useExpression, """
+ () => GetFirst(1, 2): 1
+ () => GetFirst(1, 2): 1
+ () => GetFirst(1, 2): 1
+ """));
verifier.VerifyDiagnostics();
}
@@ -806,7 +835,7 @@ static void Main()
var verifier = CompileAndVerify(
comp,
expectedOutput: """
- 1
+ --: 1
""");
verifier.VerifyDiagnostics();
}
@@ -900,15 +929,15 @@ static void Main()
{
var verifier = CompileAndVerify(
comp,
- expectedOutput: """
- 1
- 1
- 1
- 1
- 1
- 1
- 1
- """);
+ expectedOutput: IncludeExpression(useExpression, """
+ () => GetFirst(Convert(1, Object), Convert(2, Object), Convert(3, Object)): 1
+ () => GetFirst(Convert(1, Object), Convert(2, Object), Convert(3, Object)): 1
+ () => GetFirst(Convert(1, Object), Convert(2, Object), null): 1
+ () => GetFirst(Convert(1, Object), null, null): 1
+ () => GetFirst(Convert(1, Object), Convert(2, Object), Convert(3, Object)): 1
+ () => GetFirst(Convert(1, Object), Convert(2, Object), null): 1
+ () => GetFirst(Convert(1, Object), Convert(2, Object), Convert(3, Object)): 1
+ """));
verifier.VerifyDiagnostics();
}
@@ -984,13 +1013,13 @@ static void Main()
var verifier = CompileAndVerify(
comp,
expectedOutput: """
- 1
- 1
- null
- null
- null
- null
- null
+ --: 1
+ --: 1
+ --: null
+ --: null
+ --: null
+ --: null
+ --: null
""");
verifier.VerifyDiagnostics();
}
@@ -1057,14 +1086,14 @@ static void Main()
{
var verifier = CompileAndVerify(
comp,
- expectedOutput: """
- (1, 0)
- (1, 1)
- (1, 2)
- (1, )
- (1, 2)
- (1, )
- """);
+ expectedOutput: IncludeExpression(useExpression, """
+ () => GetFirstAndParamsLength(1, new [] {}): (1, 0)
+ () => GetFirstAndParamsLength(1, new [] {2}): (1, 1)
+ () => GetFirstAndParamsLength(1, new [] {2, 3}): (1, 2)
+ () => GetFirstAndParamsLength(1, null): (1, )
+ () => GetFirstAndParamsLength(1, new [] {2, 3}): (1, 2)
+ () => GetFirstAndParamsLength(1, null): (1, )
+ """));
verifier.VerifyDiagnostics();
}
@@ -1101,7 +1130,7 @@ static void Main()
var verifier = CompileAndVerify(
comp,
expectedOutput: """
- (1, )
+ --: (1, )
""");
verifier.VerifyDiagnostics();
}
@@ -1223,20 +1252,20 @@ static void Main()
{
var verifier = CompileAndVerify(
comp,
- expectedOutput: """
- (, 0)
- (0, 0)
- (2, 0)
- (2, 2)
- (2, 0)
- (2, )
- (2, 1)
- (0, 0)
- (2, 0)
- (2, 2)
- (2, )
- (2, )
- """);
+ expectedOutput: IncludeExpression(useExpression, """
+ () => GetSecondAndParamsLength(null, null, new [] {}): (, 0)
+ () => GetSecondAndParamsLength(1, 0, new [] {}): (0, 0)
+ () => GetSecondAndParamsLength(1, 2, new [] {}): (2, 0)
+ () => GetSecondAndParamsLength(1, 2, new [] {3, 4}): (2, 2)
+ () => GetSecondAndParamsLength(1, 2, new [] {}): (2, 0)
+ () => GetSecondAndParamsLength(1, 2, null): (2, )
+ () => GetSecondAndParamsLength(1, 2, new [] {3}): (2, 1)
+ () => GetSecondAndParamsLength(1, 0, new [] {}): (0, 0)
+ () => GetSecondAndParamsLength(1, 2, new [] {}): (2, 0)
+ () => GetSecondAndParamsLength(1, 2, new [] {3, 4}): (2, 2)
+ () => GetSecondAndParamsLength(1, 2, null): (2, )
+ () => GetSecondAndParamsLength(1, 2, null): (2, )
+ """));
verifier.VerifyDiagnostics();
}
@@ -1319,14 +1348,14 @@ static void Main()
var verifier = CompileAndVerify(
comp,
expectedOutput: """
- (2, 2)
- (2, )
- (0, )
- (2, 0)
- (2, 0)
- (2, )
- (0, 2)
- (2, 2)
+ --: (2, 2)
+ --: (2, )
+ --: (0, )
+ --: (2, 0)
+ --: (2, 0)
+ --: (2, )
+ --: (0, 2)
+ --: (2, 2)
""");
verifier.VerifyDiagnostics();
}
@@ -1413,10 +1442,10 @@ static void Main()
{
var verifier = CompileAndVerify(
comp,
- expectedOutput: """
- 1
- one
- """);
+ expectedOutput: IncludeExpression(useExpression, """
+ () => GetFirst(1, 2): 1
+ () => GetFirst("two", "one"): one
+ """));
verifier.VerifyDiagnostics();
}
@@ -1460,8 +1489,8 @@ static void Main()
var verifier = CompileAndVerify(
comp,
expectedOutput: """
- 1
- one
+ --: 1
+ --: one
""");
verifier.VerifyDiagnostics();
}
@@ -1508,10 +1537,10 @@ static void Main()
var verifier = CompileAndVerify(
comp,
expectedOutput: """
- 0
- null
- 0
- null
+ --: 0
+ --: null
+ --: 0
+ --: null
""");
verifier.VerifyDiagnostics();
}
@@ -1594,11 +1623,11 @@ static void Main()
{
var verifier = CompileAndVerify(
comp,
- expectedOutput: """
- (one, 1)
- (two, 2)
- (three, 3)
- """);
+ expectedOutput: IncludeExpression(useExpression, """
+ () => new A("one", value(Program+<>c__DisplayClass0_0).y): (one, 1)
+ () => new A("two", value(Program+<>c__DisplayClass0_0).y): (two, 2)
+ () => new A("three", value(Program+<>c__DisplayClass0_0).y): (three, 3)
+ """));
verifier.VerifyDiagnostics();
}
@@ -1636,8 +1665,8 @@ static void Main()
var verifier = CompileAndVerify(
comp,
expectedOutput: """
- (one, 1)
- """);
+ --: (one, 1)
+ """);
verifier.VerifyDiagnostics();
}
}
@@ -1693,11 +1722,11 @@ static void Main()
{
var verifier = CompileAndVerify(
comp,
- expectedOutput: """
- one
- two
- three
- """);
+ expectedOutput: IncludeExpression(useExpression, """
+ () => value(Program+<>c__DisplayClass0_0).a.get_Item(1, value(Program+<>c__DisplayClass0_0).y): one
+ () => value(Program+<>c__DisplayClass0_0).a.get_Item(2, "two"): two
+ () => value(Program+<>c__DisplayClass0_0).a.get_Item(2, value(Program+<>c__DisplayClass0_0).y): three
+ """));
verifier.VerifyDiagnostics();
}
@@ -1743,8 +1772,8 @@ static void Main()
var verifier = CompileAndVerify(
comp,
expectedOutput: """
- one
- two
+ --: one
+ --: two
""");
verifier.VerifyDiagnostics();
}
@@ -1797,11 +1826,11 @@ static void Main()
{
var verifier = CompileAndVerify(
comp,
- expectedOutput: """
- (1, one)
- (2, two)
- (3, three)
- """);
+ expectedOutput: IncludeExpression(useExpression, """
+ () => Invoke(value(Program+<>c__DisplayClass0_0).d, 1, "one"): (1, one)
+ () => Invoke(value(Program+<>c__DisplayClass0_0).d, 2, "two"): (2, two)
+ () => Invoke(value(Program+<>c__DisplayClass0_0).d, 3, "three"): (3, three)
+ """));
verifier.VerifyDiagnostics();
}
@@ -1840,7 +1869,7 @@ static void Main()
var verifier = CompileAndVerify(
comp,
expectedOutput: """
- (1, one)
+ --: (1, one)
""");
verifier.VerifyDiagnostics();
}
From f48800ac0fbcabae0b6078edb4fb925f2e3479bb Mon Sep 17 00:00:00 2001
From: Charles Stoner <10732005+cston@users.noreply.github.com>
Date: Tue, 8 Apr 2025 21:20:03 -0700
Subject: [PATCH 11/14] Convert
---
...xpressionOptionalAndNamedArgumentsTests.cs | 136 +++++++++---------
1 file changed, 68 insertions(+), 68 deletions(-)
diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
index dacc153a746e5..94129d43b0dd5 100644
--- a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
@@ -716,7 +716,7 @@ public static class A
public static string GetValue(
[Optional]
{{(includeDefaultParameterValue ? "[DefaultParameterValue(null)]" : "")}}
- params object[] args)
+ params int[] args)
{
return (args is null) ? "null" : args.Length.ToString();
}
@@ -739,7 +739,7 @@ static void Main()
[sourceB, GetUtilities(useExpression)],
references: [refA],
expectedOutput: IncludeExpression(useExpression, """
- () => GetValue(new [] {Convert(1, Object), Convert(2, Object), Convert(3, Object)}): 3
+ () => GetValue(new [] {1, 2, 3}): 3
() => GetValue(new [] {}): 0
"""));
verifier.VerifyDiagnostics();
@@ -885,13 +885,13 @@ class Program
{
static void Main()
{
- Utils.Report(() => A.GetFirst(first: 1, second: 2, third: 3));
- Utils.Report(() => A.GetFirst(first: 1, 2, 3));
- Utils.Report(() => A.GetFirst(first: 1, 2));
- Utils.Report(() => A.GetFirst(first: 1));
- Utils.Report(() => A.GetFirst(1, second: 2, 3));
- Utils.Report(() => A.GetFirst(1, second: 2));
- Utils.Report(() => A.GetFirst(1, 2, third: 3));
+ Utils.Report(() => A.GetFirst(first: 1, second: 2, third: 3));
+ Utils.Report(() => A.GetFirst(first: 1, 2, 3));
+ Utils.Report(() => A.GetFirst(first: 1, 2));
+ Utils.Report(() => A.GetFirst(first: 1));
+ Utils.Report(() => A.GetFirst(1, second: 2, 3));
+ Utils.Report(() => A.GetFirst(1, second: 2));
+ Utils.Report(() => A.GetFirst(1, 2, third: 3));
}
}
""";
@@ -904,39 +904,39 @@ static void Main()
{
comp.VerifyEmitDiagnostics(
// (5,28): error CS0853: An expression tree may not contain a named argument specification
- // Utils.Report(() => A.GetFirst(first: 1, second: 2, third: 3));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(first: 1, second: 2, third: 3)").WithLocation(5, 28),
+ // Utils.Report(() => A.GetFirst(first: 1, second: 2, third: 3));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(first: 1, second: 2, third: 3)").WithLocation(5, 28),
// (6,28): error CS0853: An expression tree may not contain a named argument specification
- // Utils.Report(() => A.GetFirst(first: 1, 2, 3));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(first: 1, 2, 3)").WithLocation(6, 28),
+ // Utils.Report(() => A.GetFirst(first: 1, 2, 3));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(first: 1, 2, 3)").WithLocation(6, 28),
// (7,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Utils.Report(() => A.GetFirst(first: 1, 2));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst(first: 1, 2)").WithLocation(7, 28),
+ // Utils.Report(() => A.GetFirst(first: 1, 2));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst(first: 1, 2)").WithLocation(7, 28),
// (8,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Utils.Report(() => A.GetFirst(first: 1));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst(first: 1)").WithLocation(8, 28),
+ // Utils.Report(() => A.GetFirst(first: 1));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst(first: 1)").WithLocation(8, 28),
// (9,28): error CS0853: An expression tree may not contain a named argument specification
- // Utils.Report(() => A.GetFirst(1, second: 2, 3));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(1, second: 2, 3)").WithLocation(9, 28),
+ // Utils.Report(() => A.GetFirst(1, second: 2, 3));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(1, second: 2, 3)").WithLocation(9, 28),
// (10,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Utils.Report(() => A.GetFirst(1, second: 2));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst(1, second: 2)").WithLocation(10, 28),
+ // Utils.Report(() => A.GetFirst(1, second: 2));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst(1, second: 2)").WithLocation(10, 28),
// (11,28): error CS0853: An expression tree may not contain a named argument specification
- // Utils.Report(() => A.GetFirst(1, 2, third: 3));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(1, 2, third: 3)").WithLocation(11, 28));
+ // Utils.Report(() => A.GetFirst(1, 2, third: 3));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(1, 2, third: 3)").WithLocation(11, 28));
}
else
{
var verifier = CompileAndVerify(
comp,
expectedOutput: IncludeExpression(useExpression, """
- () => GetFirst(Convert(1, Object), Convert(2, Object), Convert(3, Object)): 1
- () => GetFirst(Convert(1, Object), Convert(2, Object), Convert(3, Object)): 1
- () => GetFirst(Convert(1, Object), Convert(2, Object), null): 1
- () => GetFirst(Convert(1, Object), null, null): 1
- () => GetFirst(Convert(1, Object), Convert(2, Object), Convert(3, Object)): 1
- () => GetFirst(Convert(1, Object), Convert(2, Object), null): 1
- () => GetFirst(Convert(1, Object), Convert(2, Object), Convert(3, Object)): 1
+ () => GetFirst(1, 2, 3): 1
+ () => GetFirst(1, 2, 3): 1
+ () => GetFirst(1, 2, 0): 1
+ () => GetFirst(1, 0, 0): 1
+ () => GetFirst(1, 2, 3): 1
+ () => GetFirst(1, 2, 0): 1
+ () => GetFirst(1, 2, 3): 1
"""));
verifier.VerifyDiagnostics();
}
@@ -946,13 +946,13 @@ class Program
{
static void Main()
{
- Utils.Report(() => A.GetFirst(third:3, second: 2, first: 1));
- Utils.Report(() => A.GetFirst(second:2, first: 1));
- Utils.Report(() => A.GetFirst(second:2, third: 3));
- Utils.Report(() => A.GetFirst(second:2));
- Utils.Report(() => A.GetFirst(third:3, second: 2));
- Utils.Report(() => A.GetFirst(third:3));
- Utils.Report(() => A.GetFirst());
+ Utils.Report(() => A.GetFirst(third:3, second: 2, first: 1));
+ Utils.Report(() => A.GetFirst(second:2, first: 1));
+ Utils.Report(() => A.GetFirst(second:2, third: 3));
+ Utils.Report(() => A.GetFirst(second:2));
+ Utils.Report(() => A.GetFirst(third:3, second: 2));
+ Utils.Report(() => A.GetFirst(third:3));
+ Utils.Report(() => A.GetFirst());
}
}
""";
@@ -965,48 +965,48 @@ static void Main()
{
comp.VerifyEmitDiagnostics(
// (5,28): error CS0853: An expression tree may not contain a named argument specification
- // Utils.Report(() => A.GetFirst(third:3, second: 2, first: 1));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(third:3, second: 2, first: 1)").WithLocation(5, 28),
+ // Utils.Report(() => A.GetFirst(third:3, second: 2, first: 1));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "A.GetFirst(third:3, second: 2, first: 1)").WithLocation(5, 28),
// (6,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Utils.Report(() => A.GetFirst(second:2, first: 1));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst(second:2, first: 1)").WithLocation(6, 28),
+ // Utils.Report(() => A.GetFirst(second:2, first: 1));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst(second:2, first: 1)").WithLocation(6, 28),
// (7,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Utils.Report(() => A.GetFirst(second:2, third: 3));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst(second:2, third: 3)").WithLocation(7, 28),
+ // Utils.Report(() => A.GetFirst(second:2, third: 3));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst(second:2, third: 3)").WithLocation(7, 28),
// (8,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Utils.Report(() => A.GetFirst(second:2));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst(second:2)").WithLocation(8, 28),
+ // Utils.Report(() => A.GetFirst(second:2));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst(second:2)").WithLocation(8, 28),
// (9,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Utils.Report(() => A.GetFirst(third:3, second: 2));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst(third:3, second: 2)").WithLocation(9, 28),
+ // Utils.Report(() => A.GetFirst(third:3, second: 2));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst(third:3, second: 2)").WithLocation(9, 28),
// (10,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Utils.Report(() => A.GetFirst(third:3));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst(third:3)").WithLocation(10, 28),
+ // Utils.Report(() => A.GetFirst(third:3));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst(third:3)").WithLocation(10, 28),
// (11,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
- // Utils.Report(() => A.GetFirst());
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst()").WithLocation(11, 28));
+ // Utils.Report(() => A.GetFirst());
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetFirst()").WithLocation(11, 28));
}
else if (useExpression)
{
comp.VerifyEmitDiagnostics(
// (5,28): error CS9307: An expression tree may not contain a named argument specification out of position
- // Utils.Report(() => A.GetFirst(third:3, second: 2, first: 1));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(third:3, second: 2, first: 1)").WithLocation(5, 28),
+ // Utils.Report(() => A.GetFirst(third:3, second: 2, first: 1));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(third:3, second: 2, first: 1)").WithLocation(5, 28),
// (6,28): error CS9307: An expression tree may not contain a named argument specification out of position
- // Utils.Report(() => A.GetFirst(second:2, first: 1));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(second:2, first: 1)").WithLocation(6, 28),
+ // Utils.Report(() => A.GetFirst(second:2, first: 1));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(second:2, first: 1)").WithLocation(6, 28),
// (7,28): error CS9307: An expression tree may not contain a named argument specification out of position
- // Utils.Report(() => A.GetFirst(second:2, third: 3));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(second:2, third: 3)").WithLocation(7, 28),
+ // Utils.Report(() => A.GetFirst(second:2, third: 3));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(second:2, third: 3)").WithLocation(7, 28),
// (8,28): error CS9307: An expression tree may not contain a named argument specification out of position
- // Utils.Report(() => A.GetFirst(second:2));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(second:2)").WithLocation(8, 28),
+ // Utils.Report(() => A.GetFirst(second:2));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(second:2)").WithLocation(8, 28),
// (9,28): error CS9307: An expression tree may not contain a named argument specification out of position
- // Utils.Report(() => A.GetFirst(third:3, second: 2));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(third:3, second: 2)").WithLocation(9, 28),
+ // Utils.Report(() => A.GetFirst(third:3, second: 2));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(third:3, second: 2)").WithLocation(9, 28),
// (10,28): error CS9307: An expression tree may not contain a named argument specification out of position
- // Utils.Report(() => A.GetFirst(third:3));
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(third:3)").WithLocation(10, 28));
+ // Utils.Report(() => A.GetFirst(third:3));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgumentOutOfPosition, "A.GetFirst(third:3)").WithLocation(10, 28));
}
else
{
@@ -1015,11 +1015,11 @@ static void Main()
expectedOutput: """
--: 1
--: 1
- --: null
- --: null
- --: null
- --: null
- --: null
+ --: 0
+ --: 0
+ --: 0
+ --: 0
+ --: 0
""");
verifier.VerifyDiagnostics();
}
From 28d3bd699f2990a9159439f40af02991a328ba93 Mon Sep 17 00:00:00 2001
From: Charles Stoner <10732005+cston@users.noreply.github.com>
Date: Tue, 8 Apr 2025 21:23:09 -0700
Subject: [PATCH 12/14] Formatting
---
.../CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs
index 9444f9be5f192..759e12b5e3d76 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs
@@ -13111,7 +13111,8 @@ public static string Index(int minSessions = 0)
comp.VerifyDiagnostics(
// (10,40): error CS0853: An expression tree may not contain a named argument specification
// Expression myET = x => Index(minSessions:5);
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "Index(minSessions:5)").WithLocation(10, 40));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "Index(minSessions:5)").WithLocation(10, 40)
+ );
}
else
{
@@ -13145,7 +13146,8 @@ static void Main()
comp.VerifyDiagnostics(
// (10,41): error CS0853: An expression tree may not contain a named argument specification
// Expression> f = () => new List { 1 } [index: 0];
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "new List { 1 } [index: 0]").WithLocation(10, 41));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsNamedArgument, "new List { 1 } [index: 0]").WithLocation(10, 41)
+ );
}
else
{
@@ -13183,7 +13185,8 @@ public static string Index(int minSessions = 0)
comp.VerifyDiagnostics(
// (10,40): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
// Expression myET = x => Index();
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "Index()").WithLocation(10, 40));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "Index()").WithLocation(10, 40)
+ );
}
else
{
From e158c8de3cbf5124a21bddbdceb16a87f357c11c Mon Sep 17 00:00:00 2001
From: Charles Stoner <10732005+cston@users.noreply.github.com>
Date: Wed, 9 Apr 2025 08:29:51 -0700
Subject: [PATCH 13/14] Address feedback
---
...xpressionOptionalAndNamedArgumentsTests.cs | 85 +++++--------------
.../Test/Utilities/CSharp/CSharpTestBase.cs | 2 +-
2 files changed, 23 insertions(+), 64 deletions(-)
diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
index 94129d43b0dd5..6ce25495dc23a 100644
--- a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
@@ -82,6 +82,7 @@ public void OptionalParameter_01(
bool useCompilationReference)
{
string sourceA = $$"""
+ #pragma warning disable 9200 // default value is specified for 'ref readonly' parameter
public static class A
{
public static T GetValue({{refKind}} T t = default) => t;
@@ -131,17 +132,7 @@ static void Main()
() => GetValue(null): null
() => GetValue(value(S)): S
"""));
- if (useCompilationReference && refKind == "ref readonly")
- {
- verifier.VerifyDiagnostics(
- // (3,52): warning CS9200: A default value is specified for 'ref readonly' parameter 't', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
- // public static T GetValue(ref readonly T t = default) => t;
- Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "default").WithArguments("t").WithLocation(3, 52));
- }
- else
- {
- verifier.VerifyDiagnostics();
- }
+ verifier.VerifyDiagnostics();
}
}
@@ -153,6 +144,7 @@ public void OptionalParameter_02(
bool useCompilationReference)
{
string sourceA = $$"""
+ #pragma warning disable 9200 // default value is specified for 'ref readonly' parameter
public static class A
{
public static int GetIntValue({{refKind}} int i = 10) => i;
@@ -182,23 +174,7 @@ static void Main()
() => GetStringValue("default"): default
() => GetObjectValue(null): null
"""));
- if (useCompilationReference && refKind == "ref readonly")
- {
- verifier.VerifyDiagnostics(
- // (3,56): warning CS9200: A default value is specified for 'ref readonly' parameter 'i', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
- // public static int GetIntValue(ref readonly int i = 10) => i;
- Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "10").WithArguments("i").WithLocation(3, 56),
- // (4,65): warning CS9200: A default value is specified for 'ref readonly' parameter 's', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
- // public static string GetStringValue(ref readonly string s = "default") => s;
- Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, @"""default""").WithArguments("s").WithLocation(4, 65),
- // (5,65): warning CS9200: A default value is specified for 'ref readonly' parameter 'o', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
- // public static object GetObjectValue(ref readonly object o = null) => o;
- Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "null").WithArguments("o").WithLocation(5, 65));
- }
- else
- {
- verifier.VerifyDiagnostics();
- }
+ verifier.VerifyDiagnostics();
}
[Theory]
@@ -209,6 +185,7 @@ public void OptionalParameter_AndParams(
bool useCompilationReference)
{
string sourceA = $$"""
+ #pragma warning disable 9200 // default value is specified for 'ref readonly' parameter
public static class A
{
public static T GetValue({{refKind}} T x, {{refKind}} T y = default, params T[] args) => y;
@@ -239,35 +216,16 @@ static void Main()
"""));
if (refKind == "ref readonly")
{
- if (useCompilationReference)
- {
- verifier.VerifyDiagnostics(
- // (3,70): warning CS9200: A default value is specified for 'ref readonly' parameter 'y', but 'ref readonly' should be used only for references. Consider declaring the parameter as 'in'.
- // public static T GetValue(ref readonly T x, ref readonly T y = default, params T[] args) => y;
- Diagnostic(ErrorCode.WRN_RefReadonlyParameterDefaultValue, "default").WithArguments("y").WithLocation(3, 70),
- // (8,44): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter
- // Utils.Report(() => A.GetValue(1));
- Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "1").WithArguments("1").WithLocation(8, 44),
- // (9,44): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter
- // Utils.Report(() => A.GetValue(2, 3, 4));
- Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "2").WithArguments("1").WithLocation(9, 44),
- // (9,47): warning CS9193: Argument 2 should be a variable because it is passed to a 'ref readonly' parameter
- // Utils.Report(() => A.GetValue(2, 3, 4));
- Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "3").WithArguments("2").WithLocation(9, 47));
- }
- else
- {
- verifier.VerifyDiagnostics(
- // (8,44): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter
- // Utils.Report(() => A.GetValue(1));
- Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "1").WithArguments("1").WithLocation(8, 44),
- // (9,44): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter
- // Utils.Report(() => A.GetValue(2, 3, 4));
- Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "2").WithArguments("1").WithLocation(9, 44),
- // (9,47): warning CS9193: Argument 2 should be a variable because it is passed to a 'ref readonly' parameter
- // Utils.Report(() => A.GetValue(2, 3, 4));
- Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "3").WithArguments("2").WithLocation(9, 47));
- }
+ verifier.VerifyDiagnostics(
+ // (8,44): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter
+ // Utils.Report(() => A.GetValue(1));
+ Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "1").WithArguments("1").WithLocation(8, 44),
+ // (9,44): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter
+ // Utils.Report(() => A.GetValue(2, 3, 4));
+ Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "2").WithArguments("1").WithLocation(9, 44),
+ // (9,47): warning CS9193: Argument 2 should be a variable because it is passed to a 'ref readonly' parameter
+ // Utils.Report(() => A.GetValue(2, 3, 4));
+ Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "3").WithArguments("2").WithLocation(9, 47));
}
else
{
@@ -432,11 +390,11 @@ static void Main()
[CombinatorialData]
public void OptionalParameter_CollectionInitializer(
[CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
- bool useExpression,
- bool useIn)
+ [CombinatorialValues("", "in", "ref readonly")] string refKind,
+ bool useExpression)
{
- string refKind = useIn ? "in" : "";
string sourceA = $$"""
+ #pragma warning disable 9200 // default value is specified for 'ref readonly' parameter
using System.Collections;
using System.Collections.Generic;
using System.Text;
@@ -459,6 +417,7 @@ public override string ToString()
}
""";
string sourceB = """
+ #pragma warning disable 9193 // Argument should be a variable because it is passed to a 'ref readonly' parameter
class Program
{
static void Main()
@@ -474,11 +433,11 @@ static void Main()
if (languageVersion == LanguageVersion.CSharp13 && useExpression)
{
comp.VerifyEmitDiagnostics(
- // (5,76): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // (6,76): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
// Utils.Report(() => new MyCollection() { { "one", 1 }, { "two" } });
- Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, @"{ ""two"" }").WithLocation(5, 76));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, @"{ ""two"" }").WithLocation(6, 76));
}
- else if (useIn)
+ else if (refKind != "")
{
// Expression does not support initializers with ref parameters at runtime.
comp.VerifyEmitDiagnostics();
diff --git a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs
index 724caf2c1654d..671bb494774e3 100644
--- a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs
+++ b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs
@@ -37,7 +37,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Test.Utilities
{
public abstract class CSharpTestBase : CommonTestBase
{
- public static readonly TheoryData LanguageVersions13AndNewer = new([LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext]);
+ public static readonly TheoryData LanguageVersions13AndNewer = new TheoryData([LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext]);
protected static readonly string NullableAttributeDefinition = @"
namespace System.Runtime.CompilerServices
From 5b203cbd85e96837e6b50df9d0f7d6fdb43db5dc Mon Sep 17 00:00:00 2001
From: Charles Stoner <10732005+cston@users.noreply.github.com>
Date: Wed, 9 Apr 2025 13:52:58 -0700
Subject: [PATCH 14/14] Overloads and optional arguments
---
...xpressionOptionalAndNamedArgumentsTests.cs | 102 ++++++++++++++++++
1 file changed, 102 insertions(+)
diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
index 6ce25495dc23a..6cda4a6ea0db4 100644
--- a/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/Semantics/ExpressionOptionalAndNamedArgumentsTests.cs
@@ -233,6 +233,108 @@ static void Main()
}
}
+ [Theory]
+ [CombinatorialData]
+ public void OptionalParameter_Overloads_01(
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ bool useExpression,
+ bool useCompilationReference)
+ {
+ string sourceA = $$"""
+ public static class A
+ {
+ public static (int, int, int) GetArgs(int x, int y = -2, params int[] z) => (x, y, z.Length);
+ public static object GetArgs(object x) => x;
+ }
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = AsReference(comp, useCompilationReference);
+
+ string sourceB = $$"""
+ class Program
+ {
+ static void Main()
+ {
+ Utils.Report(() => A.GetArgs(10, 20));
+ Utils.Report(() => A.GetArgs(10));
+ }
+ }
+ """;
+ comp = CreateCompilation(
+ [sourceB, GetUtilities(useExpression)],
+ references: [refA],
+ parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
+ options: TestOptions.ReleaseExe);
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (6,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Utils.Report(() => A.GetArgs(10));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetArgs(10)").WithLocation(6, 28));
+ }
+ else
+ {
+ var verifier = CompileAndVerify(
+ comp,
+ expectedOutput: IncludeExpression(useExpression, """
+ () => GetArgs(10, 20, new [] {}): (10, 20, 0)
+ () => GetArgs(10, -2, new [] {}): (10, -2, 0)
+ """));
+ verifier.VerifyDiagnostics();
+ }
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public void OptionalParameter_Overloads_02(
+ [CombinatorialValues(LanguageVersion.CSharp13, LanguageVersion.Preview, LanguageVersionFacts.CSharpNext)] LanguageVersion languageVersion,
+ bool useExpression,
+ bool useCompilationReference)
+ {
+ string sourceA = $$"""
+ public static class A
+ {
+ public static (int, int, int) GetArgs(int x, int y, int z = -3) => (x, y, z);
+ public static (int, int) GetArgs(int x, params int[] y) => (x, y.Length);
+ }
+ """;
+ var comp = CreateCompilation(sourceA);
+ var refA = AsReference(comp, useCompilationReference);
+
+ string sourceB = $$"""
+ class Program
+ {
+ static void Main()
+ {
+ Utils.Report(() => A.GetArgs(10, 20, 30));
+ Utils.Report(() => A.GetArgs(10, 20));
+ }
+ }
+ """;
+ comp = CreateCompilation(
+ [sourceB, GetUtilities(useExpression)],
+ references: [refA],
+ parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
+ options: TestOptions.ReleaseExe);
+ if (languageVersion == LanguageVersion.CSharp13 && useExpression)
+ {
+ comp.VerifyEmitDiagnostics(
+ // (6,28): error CS0854: An expression tree may not contain a call or invocation that uses optional arguments
+ // Utils.Report(() => A.GetArgs(10, 20));
+ Diagnostic(ErrorCode.ERR_ExpressionTreeContainsOptionalArgument, "A.GetArgs(10, 20)").WithLocation(6, 28));
+ }
+ else
+ {
+ var verifier = CompileAndVerify(
+ comp,
+ expectedOutput: IncludeExpression(useExpression, """
+ () => GetArgs(10, 20, 30): (10, 20, 30)
+ () => GetArgs(10, 20, -3): (10, 20, -3)
+ """));
+ verifier.VerifyDiagnostics();
+ }
+ }
+
[Theory]
[CombinatorialData]
public void OptionalParameter_Constructor(