diff --git a/src/Compilers/CSharp/Portable/Binder/ExecutableCodeBinder.cs b/src/Compilers/CSharp/Portable/Binder/ExecutableCodeBinder.cs
index e08152589f822..49fc5d773b0e7 100644
--- a/src/Compilers/CSharp/Portable/Binder/ExecutableCodeBinder.cs
+++ b/src/Compilers/CSharp/Portable/Binder/ExecutableCodeBinder.cs
@@ -147,6 +147,10 @@ public static void ValidateIteratorMethod(CSharpCompilation compilation, MethodS
Error(diagnostics, ErrorCode.ERR_BadIteratorReturn, errorLocation, iterator, returnType);
}
}
+ else if (elementType.IsRefLikeOrAllowsRefLikeType())
+ {
+ Error(diagnostics, ErrorCode.ERR_IteratorRefLikeElementType, errorLocation);
+ }
bool asyncInterface = InMethodBinder.IsAsyncStreamInterface(compilation, refKind, returnType);
if (asyncInterface && !iterator.IsAsync)
diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index 62df9574a17fb..890bab5adcfcb 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -8014,4 +8014,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
Property accessor should use 'field' because the other accessor is using it.
+
+ Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
index dacf87a0f6bb6..90e45ee89de30 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@@ -2349,6 +2349,8 @@ internal enum ErrorCode
WRN_UnassignedInternalRefField = 9265,
WRN_AccessorDoesNotUseBackingField = 9266,
+ ERR_IteratorRefLikeElementType = 9267,
+
// 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/Portable/Errors/ErrorFacts.cs b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
index b1d4d91c2dc55..b3c03386122fa 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
@@ -2466,6 +2466,7 @@ or ErrorCode.ERR_PartialPropertyDuplicateInitializer
or ErrorCode.WRN_UninitializedNonNullableBackingField
or ErrorCode.WRN_UnassignedInternalRefField
or ErrorCode.WRN_AccessorDoesNotUseBackingField
+ or ErrorCode.ERR_IteratorRefLikeElementType
=> 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.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
index e45a2c37ce756..7476e0bcc3709 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
@@ -1327,6 +1327,11 @@
Metoda {0} s blokem iterátoru musí být asynchronní, aby vrátila {1}.
+
+
+ Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+
+ Kontextové klíčové slovo var se nedá použít jako explicitní návratový typ lambda.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
index aaba77e8f76bb..10730f1c39e1c 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
@@ -1327,6 +1327,11 @@
Die Methode "{0}" mit einem Iteratorblock muss "async" lauten, um "{1}" zurückzugeben.
+
+
+ Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+
+ Das kontextbezogene Schlüsselwort „var“ kann nicht als expliziter Lambdarückgabetyp verwendet werden.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
index 9cce548939e77..66a0863ed582e 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
@@ -1327,6 +1327,11 @@
El método "{0}" con un bloqueo de iterador debe ser "asincrónico" para devolver "{1}"
+
+
+ Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+
+ La palabra clave contextual "var" no se puede utilizar como un tipo de retorno lambda explícito
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
index 98751bfe95a1d..3e10b174a09f3 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
@@ -1327,6 +1327,11 @@
La méthode '{0}' avec un bloc itérateur doit être 'async' pour retourner '{1}'
+
+
+ Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+
+ Le mot clé contextuel 'var' ne peut pas être utilisé comme type de retour lambda explicite
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
index 64696f2e146ec..671335b66b647 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
@@ -1327,6 +1327,11 @@
Il metodo '{0}' con un blocco iteratore deve essere 'async' per restituire '{1}'
+
+
+ Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+
+ Non è possibile usare la parola chiave contestuale 'var' come tipo restituito dell’espressione lambda
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
index d44b325ae6e33..cbb14da8e0c4f 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
@@ -1327,6 +1327,11 @@
反復子ブロックを伴うメソッド '{0}' が '{1}' を返すには 'async' でなければなりません
+
+
+ Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+
+ コンテキスト キーワード "var" を明示的なラムダ戻り値の型として使用することはできません
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
index d2ca43b953015..a9d62274be170 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
@@ -1327,6 +1327,11 @@
'{1}'을(를) 반환하려면 반복기 블록이 있는 '{0}' 메서드가 '비동기'여야 합니다.
+
+
+ Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+
+ 'var' 상황별 키워드는 명시적 람다 반환 형식으로 사용할 수 없습니다.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
index e86dfab66f0fb..1d87586dfcefa 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
@@ -1327,6 +1327,11 @@
Metoda „{0}” z blokiem iteratora musi być oznaczona jako „async”, aby zwrócić „{1}”
+
+
+ Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+
+ Kontekstowego słowa kluczowego „var” nie można użyć jako jawnego zwracanego typu lambda
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
index edbfe816df3fd..c687d6dfe45a9 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
@@ -1327,6 +1327,11 @@
O método '{0}' com um bloco do iterador deve ser 'async' para retornar '{1}'
+
+
+ Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+
+ A palavra-chave contextual 'var' não pode ser usada como um tipo de retorno de lambda explícito
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
index ae613e0a31533..5af1f7baafe53 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
@@ -1327,6 +1327,11 @@
Чтобы возвращать "{1}", метод "{0}" с блоком итератора должен быть асинхронным ("async").
+
+
+ Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+
+ Контекстное ключевое слово "var" нельзя использовать в качестве явного типа возвращаемого значения лямбда-выражения
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
index 84b578ba8453e..74e0903ece0fd 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
@@ -1327,6 +1327,11 @@
Yineleyici bloku olan '{0}' yönteminin '{1}' döndürmek için 'zaman uyumsuz' olması gerekir
+
+
+ Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+
+ Bağlamsal 'var' anahtar sözcüğü, açık lambda dönüş türü olarak kullanılamaz
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
index f4df4486e8b29..3933ad33c11ab 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
@@ -1327,6 +1327,11 @@
具有迭代器块的方法“{0}”必须是“异步的”,这样才能返回“{1}”
+
+
+ Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+
+ 上下文关键字 “var” 不能用作显式 lambda 返回类型
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
index f39a0815a3d24..f13662bc08649 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
@@ -1327,6 +1327,11 @@
具有迭代區塊的方法 '{0}' 必須為「非同步」才能傳回 '{1}'
+
+
+ Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+
+ 內容關鍵字 'var' 不得做為明確的 Lambda 傳回型別
diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs
index c8b79ddce9d23..a607dbf9aa094 100644
--- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs
@@ -641,7 +641,10 @@ ref struct S
{
// source(4,65): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'IAsyncEnumerable'
// static async System.Collections.Generic.IAsyncEnumerable M()
- Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "M").WithArguments("System.Collections.Generic.IAsyncEnumerable", "T", "S").WithLocation(4, 65)
+ Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "M").WithArguments("System.Collections.Generic.IAsyncEnumerable", "T", "S").WithLocation(4, 65),
+ // source(4,65): error CS9267: Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+ // static async System.Collections.Generic.IAsyncEnumerable M()
+ Diagnostic(ErrorCode.ERR_IteratorRefLikeElementType, "M").WithLocation(4, 65)
};
var comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe);
@@ -655,6 +658,9 @@ ref struct S
// source(4,65): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'IAsyncEnumerable'
// static async System.Collections.Generic.IAsyncEnumerable M()
Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "M").WithArguments("System.Collections.Generic.IAsyncEnumerable", "T", "S").WithLocation(4, 65),
+ // source(4,65): error CS9267: Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+ // static async System.Collections.Generic.IAsyncEnumerable M()
+ Diagnostic(ErrorCode.ERR_IteratorRefLikeElementType, "M").WithLocation(4, 65),
// source(11,24): error CS9202: Feature 'ref and unsafe in async and iterator methods' is not available in C# 12.0. Please use language version 13.0 or greater.
// await foreach (var s in M())
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion12, "var").WithArguments("ref and unsafe in async and iterator methods", "13.0").WithLocation(11, 24));
diff --git a/src/Compilers/CSharp/Test/Emit3/RefStructInterfacesTests.cs b/src/Compilers/CSharp/Test/Emit3/RefStructInterfacesTests.cs
index 9eb341f5bb670..b505c4518ad63 100644
--- a/src/Compilers/CSharp/Test/Emit3/RefStructInterfacesTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/RefStructInterfacesTests.cs
@@ -28992,5 +28992,176 @@ public ReadOnlySpan GetDirectBuffer2()
Diagnostic(ErrorCode.ERR_RefReturnStructThis, "directBuffer").WithLocation(2000, 16)
);
}
+
+ [Fact]
+ [WorkItem("https://github.com/dotnet/roslyn/issues/75569")]
+ [WorkItem("https://github.com/dotnet/roslyn/issues/75577")]
+ public void Iterator_01()
+ {
+ var source =
+@"
+using System;
+using System.Collections.Generic;
+
+static class CSharpCompilerCrash
+{
+ public static IEnumerable> Lines(string data)
+ {
+ yield break;
+ }
+}
+";
+ var comp = CreateCompilation(source, targetFramework: TargetFramework.Net90);
+ comp.VerifyEmitDiagnostics(
+ // (7,51): error CS9266: Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+ // public static IEnumerable> Lines(string data)
+ Diagnostic(ErrorCode.ERR_IteratorRefLikeElementType, "Lines").WithLocation(7, 51)
+ );
+ }
+
+ [Fact]
+ [WorkItem("https://github.com/dotnet/roslyn/issues/75569")]
+ [WorkItem("https://github.com/dotnet/roslyn/issues/75577")]
+ public void Iterator_02()
+ {
+ var source =
+@"
+using System.Collections.Generic;
+
+static class CSharpCompilerCrash
+{
+ static IEnumerable B()
+ {
+ yield break;
+ }
+
+ ref struct A;
+}
+";
+ var comp = CreateCompilation(source, targetFramework: TargetFramework.Net90);
+ comp.VerifyEmitDiagnostics(
+ // (6,27): error CS9266: Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+ // static IEnumerable B()
+ Diagnostic(ErrorCode.ERR_IteratorRefLikeElementType, "B").WithLocation(6, 27)
+ );
+ }
+
+ [Fact]
+ [WorkItem("https://github.com/dotnet/roslyn/issues/75569")]
+ [WorkItem("https://github.com/dotnet/roslyn/issues/75577")]
+ public void Iterator_03()
+ {
+ var source =
+@"
+using System.Collections.Generic;
+
+static class CSharpCompilerCrash
+{
+ static IEnumerator B
+ {
+ get
+ {
+ yield break;
+ }
+ }
+
+ ref struct A;
+}
+";
+ var comp = CreateCompilation(source, targetFramework: TargetFramework.Net90);
+ comp.VerifyEmitDiagnostics(
+ // (8,9): error CS9266: Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+ // get
+ Diagnostic(ErrorCode.ERR_IteratorRefLikeElementType, "get").WithLocation(8, 9)
+ );
+ }
+
+ [Fact]
+ [WorkItem("https://github.com/dotnet/roslyn/issues/75569")]
+ [WorkItem("https://github.com/dotnet/roslyn/issues/75577")]
+ public void Iterator_04()
+ {
+ var source =
+@"
+#pragma warning disable CS1998 // This async method lacks 'await' operators
+
+using System.Collections.Generic;
+
+static class CSharpCompilerCrash
+{
+ static async IAsyncEnumerable B()
+ {
+ yield return default;
+ yield break;
+ }
+
+ ref struct RefStructA;
+}
+";
+ var comp = CreateCompilation(source, targetFramework: TargetFramework.Net90);
+ comp.VerifyDiagnostics(
+ // (8,47): error CS9266: Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+ // static async IAsyncEnumerable B()
+ Diagnostic(ErrorCode.ERR_IteratorRefLikeElementType, "B").WithLocation(8, 47)
+ );
+ }
+
+ [Fact]
+ [WorkItem("https://github.com/dotnet/roslyn/issues/75569")]
+ [WorkItem("https://github.com/dotnet/roslyn/issues/75577")]
+ public void Iterator_05()
+ {
+ var source =
+@"
+#pragma warning disable CS1998 // This async method lacks 'await' operators
+
+using System.Collections.Generic;
+
+static class CSharpCompilerCrash
+{
+ static async IAsyncEnumerator B()
+ {
+ yield return default;
+ yield break;
+ }
+
+ ref struct RefStructA;
+}
+";
+ var comp = CreateCompilation(source, targetFramework: TargetFramework.Net90);
+ comp.VerifyDiagnostics(
+ // (8,47): error CS9266: Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+ // static async IAsyncEnumerator B()
+ Diagnostic(ErrorCode.ERR_IteratorRefLikeElementType, "B").WithLocation(8, 47)
+ );
+ }
+
+ [Fact]
+ [WorkItem("https://github.com/dotnet/roslyn/issues/75569")]
+ [WorkItem("https://github.com/dotnet/roslyn/issues/75577")]
+ public void Iterator_06()
+ {
+ var source =
+@"
+#pragma warning disable CS1998 // This async method lacks 'await' operators
+
+using System.Collections.Generic;
+
+static class CSharpCompilerCrash
+{
+ static async IAsyncEnumerator B() where T : allows ref struct
+ {
+ yield return default;
+ yield break;
+ }
+}
+";
+ var comp = CreateCompilation(source, targetFramework: TargetFramework.Net90);
+ comp.VerifyDiagnostics(
+ // (8,38): error CS9266: Element type of an iterator may not be a ref struct or a type parameter allowing ref structs
+ // static async IAsyncEnumerator B() where T : allows ref struct
+ Diagnostic(ErrorCode.ERR_IteratorRefLikeElementType, "B").WithLocation(8, 38)
+ );
+ }
}
}