diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
index c577341e48531..d884574b41d96 100644
--- a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
+++ b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
@@ -3182,21 +3182,13 @@ private BoundExpression BindOutVariableDeclarationArgument(
///
/// Reports an error when a bad special by-ref local was found.
///
- internal static void CheckRestrictedTypeInAsyncMethod(Symbol containingSymbol, TypeSymbol type, BindingDiagnosticBag diagnostics, SyntaxNode syntax, ErrorCode errorCode = ErrorCode.ERR_BadSpecialByRefLocal)
+ internal static void CheckRestrictedTypeInAsyncMethod(Symbol containingSymbol, TypeSymbol type, BindingDiagnosticBag diagnostics, SyntaxNode syntax)
{
- Debug.Assert(errorCode is ErrorCode.ERR_BadSpecialByRefLocal or ErrorCode.ERR_BadSpecialByRefUsing or ErrorCode.ERR_BadSpecialByRefLock);
if (containingSymbol.Kind == SymbolKind.Method
&& ((MethodSymbol)containingSymbol).IsAsync
&& type.IsRestrictedType())
{
- if (errorCode == ErrorCode.ERR_BadSpecialByRefLock)
- {
- Error(diagnostics, errorCode, syntax);
- }
- else
- {
- Error(diagnostics, errorCode, syntax, type);
- }
+ CheckFeatureAvailability(syntax, MessageID.IDS_FeatureRefUnsafeInIteratorAsync, diagnostics);
}
}
diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
index 9a453523f720a..faeeb28982488 100644
--- a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
+++ b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs
@@ -1170,15 +1170,9 @@ protected BoundLocalDeclaration BindVariableDeclaration(
protected bool CheckRefLocalInAsyncOrIteratorMethod(SyntaxToken identifierToken, BindingDiagnosticBag diagnostics)
{
- if (IsInAsyncMethod())
- {
- Error(diagnostics, ErrorCode.ERR_BadAsyncLocalType, identifierToken);
- return true;
- }
- else if (IsDirectlyInIterator)
+ if (IsDirectlyInIterator || IsInAsyncMethod())
{
- Error(diagnostics, ErrorCode.ERR_BadIteratorLocalType, identifierToken);
- return true;
+ return !CheckFeatureAvailability(identifierToken, MessageID.IDS_FeatureRefUnsafeInIteratorAsync, diagnostics);
}
return false;
diff --git a/src/Compilers/CSharp/Portable/Binder/LockBinder.cs b/src/Compilers/CSharp/Portable/Binder/LockBinder.cs
index c29d038662a25..0899da0cfdb69 100644
--- a/src/Compilers/CSharp/Portable/Binder/LockBinder.cs
+++ b/src/Compilers/CSharp/Portable/Binder/LockBinder.cs
@@ -64,13 +64,6 @@ internal override BoundStatement BindLockStatementParts(BindingDiagnosticBag dia
_ = diagnostics.ReportUseSite(lockTypeInfo.EnterScopeMethod, exprSyntax) ||
diagnostics.ReportUseSite(lockTypeInfo.ScopeType, exprSyntax) ||
diagnostics.ReportUseSite(lockTypeInfo.ScopeDisposeMethod, exprSyntax);
-
- CheckRestrictedTypeInAsyncMethod(
- originalBinder.ContainingMemberOrLambda,
- lockTypeInfo.ScopeType,
- diagnostics,
- exprSyntax,
- errorCode: ErrorCode.ERR_BadSpecialByRefLock);
}
BoundStatement stmt = originalBinder.BindPossibleEmbeddedStatement(_syntax.Statement, diagnostics);
diff --git a/src/Compilers/CSharp/Portable/Binder/UsingStatementBinder.cs b/src/Compilers/CSharp/Portable/Binder/UsingStatementBinder.cs
index 522d191faa3db..e35930b124152 100644
--- a/src/Compilers/CSharp/Portable/Binder/UsingStatementBinder.cs
+++ b/src/Compilers/CSharp/Portable/Binder/UsingStatementBinder.cs
@@ -119,7 +119,7 @@ internal static BoundStatement BindUsingStatementOrDeclarationFromParts(SyntaxNo
Debug.Assert(expressionOpt is not null);
if (expressionOpt.Type is not null)
{
- CheckRestrictedTypeInAsyncMethod(originalBinder.ContainingMemberOrLambda, expressionOpt.Type, diagnostics, expressionOpt.Syntax, errorCode: ErrorCode.ERR_BadSpecialByRefUsing);
+ CheckRestrictedTypeInAsyncMethod(originalBinder.ContainingMemberOrLambda, expressionOpt.Type, diagnostics, expressionOpt.Syntax);
}
}
else
diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index bca68783ecce8..546daa5c1d4b1 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -3810,7 +3810,7 @@ Give the compiler some way to differentiate the methods. For example, you can gi
__arglist is not allowed in the parameter list of async methods
- 'await' cannot be used in an expression containing the type '{0}'
+ Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary.Async methods cannot have pointer type parameters
@@ -3851,15 +3851,12 @@ Give the compiler some way to differentiate the methods. For example, you can gi
The 'async' modifier can only be used in methods that have a body.
-
- Parameters or locals of type '{0}' cannot be declared in async methods or async lambda expressions.
-
-
- A using statement resource of type '{0}' cannot be used in async methods or async lambda expressions.
-
foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct.
+
+ Parameters of type '{0}' cannot be declared in async methods or async lambda expressions.
+
Security attribute '{0}' cannot be applied to an Async method.
@@ -5290,12 +5287,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
Cannot use ref local '{0}' inside an anonymous method, lambda expression, or query expression
-
- Iterators cannot have by-reference locals
-
-
- Async methods cannot have by-reference locals
-
A reference returned by a call to '{0}' cannot be preserved across 'await' or 'yield' boundary.
@@ -7851,9 +7842,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
A value of type 'System.Threading.Lock' converted to a different type will use likely unintended monitor-based locking in 'lock' statement.
-
- A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions.
-
Lock object
@@ -7911,4 +7899,10 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
'yield return' should not be used in the body of a lock statement
+
+ ref and unsafe in async and iterator methods
+
+
+ A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+
\ No newline at end of file
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
index 08f0c3e6b45cf..b4fb86f47e14b 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@@ -1111,7 +1111,7 @@ internal enum ErrorCode
ERR_NonTaskMainCantBeAsync = 4009,
ERR_CantConvAsyncAnonFuncReturns = 4010,
ERR_BadAwaiterPattern = 4011,
- ERR_BadSpecialByRefLocal = 4012,
+ ERR_BadSpecialByRefParameter = 4012,
ERR_SpecialByRefInLambda = 4013,
WRN_UnobservedAwaitableExpression = 4014,
ERR_SynchronizedAsyncMethod = 4015,
@@ -1429,8 +1429,8 @@ internal enum ErrorCode
ERR_RefAssignmentMustHaveIdentityConversion = 8173,
ERR_ByReferenceVariableMustBeInitialized = 8174,
ERR_AnonDelegateCantUseLocal = 8175,
- ERR_BadIteratorLocalType = 8176,
- ERR_BadAsyncLocalType = 8177,
+ // ERR_BadIteratorLocalType = 8176,
+ // ERR_BadAsyncLocalType = 8177,
ERR_RefReturningCallAndAwait = 8178,
#endregion diagnostics for ref locals and ref returns introduced in C# 7
@@ -2161,7 +2161,7 @@ internal enum ErrorCode
ERR_UnscopedRefAttributeUnsupportedMemberTarget = 9101,
ERR_UnscopedRefAttributeInterfaceImplementation = 9102,
ERR_UnrecognizedRefSafetyRulesAttributeVersion = 9103,
- ERR_BadSpecialByRefUsing = 9104,
+ // ERR_BadSpecialByRefUsing = 9104,
ERR_InvalidPrimaryConstructorParameterReference = 9105,
ERR_AmbiguousPrimaryConstructorParameterAsColorColorReceiver = 9106,
@@ -2286,7 +2286,7 @@ internal enum ErrorCode
ERR_CollectionExpressionMissingAdd = 9215,
WRN_ConvertingLock = 9216,
- ERR_BadSpecialByRefLock = 9217,
+ ERR_RefLocalAcrossAwait = 9217,
ERR_CantInferMethTypeArgs_DynamicArgumentWithParamsCollections = 9218,
ERR_ParamsCollectionAmbiguousDynamicArgument = 9219,
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
index 2d0a6c799d702..4722401c000b1 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
@@ -626,6 +626,7 @@ internal static bool IsBuildOnlyDiagnostic(ErrorCode code)
case ErrorCode.ERR_InterceptableMethodMustBeOrdinary:
case ErrorCode.ERR_PossibleAsyncIteratorWithoutYield:
case ErrorCode.ERR_PossibleAsyncIteratorWithoutYieldOrAwait:
+ case ErrorCode.ERR_RefLocalAcrossAwait:
// Update src\EditorFeatures\CSharp\LanguageServer\CSharpLspBuildOnlyDiagnostics.cs
// whenever new values are added here.
return true;
@@ -1537,7 +1538,7 @@ internal static bool IsBuildOnlyDiagnostic(ErrorCode code)
case ErrorCode.ERR_NonTaskMainCantBeAsync:
case ErrorCode.ERR_CantConvAsyncAnonFuncReturns:
case ErrorCode.ERR_BadAwaiterPattern:
- case ErrorCode.ERR_BadSpecialByRefLocal:
+ case ErrorCode.ERR_BadSpecialByRefParameter:
case ErrorCode.WRN_UnobservedAwaitableExpression:
case ErrorCode.ERR_SynchronizedAsyncMethod:
case ErrorCode.ERR_BadAsyncReturnExpression:
@@ -1780,8 +1781,6 @@ internal static bool IsBuildOnlyDiagnostic(ErrorCode code)
case ErrorCode.ERR_RefAssignmentMustHaveIdentityConversion:
case ErrorCode.ERR_ByReferenceVariableMustBeInitialized:
case ErrorCode.ERR_AnonDelegateCantUseLocal:
- case ErrorCode.ERR_BadIteratorLocalType:
- case ErrorCode.ERR_BadAsyncLocalType:
case ErrorCode.ERR_PredefinedValueTupleTypeNotFound:
case ErrorCode.ERR_SemiOrLBraceOrArrowExpected:
case ErrorCode.ERR_NewWithTupleTypeSyntax:
@@ -2333,7 +2332,6 @@ internal static bool IsBuildOnlyDiagnostic(ErrorCode code)
case ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget:
case ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation:
case ErrorCode.ERR_UnrecognizedRefSafetyRulesAttributeVersion:
- case ErrorCode.ERR_BadSpecialByRefUsing:
case ErrorCode.ERR_InvalidPrimaryConstructorParameterReference:
case ErrorCode.ERR_AmbiguousPrimaryConstructorParameterAsColorColorReceiver:
case ErrorCode.WRN_CapturedPrimaryConstructorParameterPassedToBase:
@@ -2422,7 +2420,6 @@ internal static bool IsBuildOnlyDiagnostic(ErrorCode code)
case ErrorCode.ERR_CollectionExpressionMissingConstructor:
case ErrorCode.ERR_CollectionExpressionMissingAdd:
case ErrorCode.WRN_ConvertingLock:
- case ErrorCode.ERR_BadSpecialByRefLock:
case ErrorCode.ERR_CantInferMethTypeArgs_DynamicArgumentWithParamsCollections:
case ErrorCode.ERR_ParamsCollectionAmbiguousDynamicArgument:
case ErrorCode.WRN_DynamicDispatchToParamsCollectionMethod:
diff --git a/src/Compilers/CSharp/Portable/Errors/MessageID.cs b/src/Compilers/CSharp/Portable/Errors/MessageID.cs
index 72f876baaa909..eb580e98e2ac6 100644
--- a/src/Compilers/CSharp/Portable/Errors/MessageID.cs
+++ b/src/Compilers/CSharp/Portable/Errors/MessageID.cs
@@ -282,6 +282,8 @@ internal enum MessageID
IDS_FeatureLockObject = MessageBase + 12841,
IDS_FeatureParamsCollections = MessageBase + 12842,
+
+ IDS_FeatureRefUnsafeInIteratorAsync = MessageBase + 12843,
}
// Message IDs may refer to strings that need to be localized.
@@ -466,6 +468,7 @@ internal static LanguageVersion RequiredVersion(this MessageID feature)
case MessageID.IDS_FeatureImplicitIndexerInitializer:
case MessageID.IDS_FeatureLockObject:
case MessageID.IDS_FeatureParamsCollections:
+ case MessageID.IDS_FeatureRefUnsafeInIteratorAsync:
return LanguageVersion.Preview;
// C# 12.0 features.
diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/IteratorAndAsyncCaptureWalker.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/IteratorAndAsyncCaptureWalker.cs
index 91d75e4f81586..d8ce97fa4088f 100644
--- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/IteratorAndAsyncCaptureWalker.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/IteratorAndAsyncCaptureWalker.cs
@@ -19,7 +19,7 @@ namespace Microsoft.CodeAnalysis.CSharp
///
///
/// Data flow analysis is used to calculate the locals. At yield/await we mark all variables as "unassigned".
- /// When a read from an unassigned variables is reported we add the variable to the captured set.
+ /// When a read from an unassigned variable is reported we add the variable to the captured set.
/// "this" parameter is captured if a reference to "this", "base" or an instance field is encountered.
/// Variables used in finally also need to be captured if there is a yield in the corresponding try block.
///
@@ -76,19 +76,33 @@ public static OrderedSet Analyze(CSharpCompilation compilation, MethodSy
foreach (var kvp in lazyDisallowedCaptures)
{
var variable = kvp.Key;
- var type = (variable.Kind == SymbolKind.Local) ? ((LocalSymbol)variable).Type : ((ParameterSymbol)variable).Type;
- if (variable is SynthesizedLocal local && local.SynthesizedKind == SynthesizedLocalKind.Spill)
+ if (variable is LocalSymbol local)
{
- Debug.Assert(local.TypeWithAnnotations.IsRestrictedType());
- diagnostics.Add(ErrorCode.ERR_ByRefTypeAndAwait, local.GetFirstLocation(), local.TypeWithAnnotations);
+ foreach (var syntax in kvp.Value)
+ {
+ if (local.TypeWithAnnotations.IsRestrictedType())
+ {
+ // CS4007: Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary.
+ diagnostics.Add(ErrorCode.ERR_ByRefTypeAndAwait, syntax.Location, local.TypeWithAnnotations);
+ }
+ else
+ {
+ Debug.Assert(local.RefKind != RefKind.None);
+ // CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+ diagnostics.Add(ErrorCode.ERR_RefLocalAcrossAwait, syntax.Location);
+ }
+ }
}
else
{
- foreach (CSharpSyntaxNode syntax in kvp.Value)
+ var parameter = (ParameterSymbol)variable;
+ Debug.Assert(parameter.TypeWithAnnotations.IsRestrictedType());
+
+ foreach (var syntax in kvp.Value)
{
- // CS4013: Instance of type '{0}' cannot be used inside an anonymous function, query expression, iterator block or async method
- diagnostics.Add(ErrorCode.ERR_SpecialByRefInLambda, syntax.Location, type);
+ // CS4007: Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary.
+ diagnostics.Add(ErrorCode.ERR_ByRefTypeAndAwait, syntax.Location, parameter.TypeWithAnnotations);
}
}
}
@@ -195,14 +209,23 @@ protected override ImmutableArray Scan(ref bool badRegion)
private void CaptureVariable(Symbol variable, SyntaxNode syntax)
{
var type = (variable.Kind == SymbolKind.Local) ? ((LocalSymbol)variable).Type : ((ParameterSymbol)variable).Type;
- if (type.IsRestrictedType())
+ if (type.IsRestrictedType() ||
+ (variable is LocalSymbol { RefKind: not RefKind.None } refLocal && !canRefLocalBeHoisted(refLocal)))
{
(_lazyDisallowedCaptures ??= new MultiDictionary()).Add(variable, syntax);
}
else
{
if (_variablesToHoist.Add(variable) && variable is LocalSymbol local && _boundRefLocalInitializers.TryGetValue(local, out var variableInitializer))
- CaptureRefInitializer(variableInitializer, syntax);
+ CaptureRefInitializer(variableInitializer, local.SynthesizedKind != SynthesizedLocalKind.UserDefined ? variableInitializer.Syntax : syntax);
+ }
+
+ static bool canRefLocalBeHoisted(LocalSymbol refLocal)
+ {
+ return refLocal.SynthesizedKind == SynthesizedLocalKind.Spill ||
+ (refLocal.SynthesizedKind == SynthesizedLocalKind.ForEachArray &&
+ refLocal.Type.HasInlineArrayAttribute(out _) &&
+ refLocal.Type.TryGetInlineArrayElementField() is not null);
}
}
diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbol.cs
index a1771beb99a70..8cce2057e5200 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbol.cs
@@ -72,7 +72,7 @@ internal void ReportAsyncParameterErrors(BindingDiagnosticBag diagnostics, Locat
}
else if (parameter.Type.IsRestrictedType())
{
- diagnostics.Add(ErrorCode.ERR_BadSpecialByRefLocal, getLocation(parameter, location), parameter.Type);
+ diagnostics.Add(ErrorCode.ERR_BadSpecialByRefParameter, getLocation(parameter, location), parameter.Type);
}
}
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
index 43a0b6a8deff2..fc8ee36929979 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
@@ -267,14 +267,14 @@
Člen záznamu {0} musí být čitelná vlastnost instance nebo pole typu {1}, která se bude shodovat s pozičním parametrem {2}.
-
-
- A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions.
+
+
+ foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct.
-
-
- Prostředek použitého příkazu typu {0} nejde použít v asynchronních metodách ani v asynchronních výrazech lambda.
+
+
+ Parameters of type '{0}' cannot be declared in async methods or async lambda expressions.
@@ -1712,6 +1712,11 @@
Pole ref lze deklarovat pouze ve struktuře ref.
+
+
+ A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+
+ Levá strana přiřazení odkazu musí být parametr Ref.
@@ -2347,6 +2352,11 @@
parametry ref readonly
+
+
+ ref and unsafe in async and iterator methods
+
+ uvolněný operátor směny
@@ -10540,8 +10550,8 @@ Poskytněte kompilátoru nějaký způsob, jak metody rozlišit. Můžete např
-
- 'Operátor await nejde použít ve výrazu, který obsahuje typ {0}.
+
+ 'Operátor await nejde použít ve výrazu, který obsahuje typ {0}.
@@ -10609,16 +10619,6 @@ Poskytněte kompilátoru nějaký způsob, jak metody rozlišit. Můžete např
Modifikátor async se dá použít jenom v metodách, které mají tělo.
-
-
- Parametry nebo lokální proměnné typu {0} nemůžou být deklarované v asynchronních metodách nebo asynchronních výrazech lambda.
-
-
-
-
- Výraz foreach nejde použít na enumerátorech typu {0} v asynchronních metodách nebo metodách iterátoru, protože {0} je struktura REF.
-
- Atribut zabezpečení {0} nejde použít pro metodu Async.
@@ -11138,7 +11138,7 @@ Potlačení upozornění zvažte jenom v případě, když určitě nechcete če
- Instance typu {0} nelze použít uvnitř vnořené funkce, výrazu dotazu, bloku iterátoru nebo asynchronní metody.
+ Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method
@@ -12449,16 +12449,6 @@ Pokud chcete odstranit toto varování, můžete místo toho použít /reference
Místní hodnotu odkazu {0} nejde použít uvnitř anonymní metody, výrazu lambda nebo výrazu dotazu.
-
-
- Iterátory nemůžou mít lokální proměnné podle odkazu.
-
-
-
-
- Asynchronní metody nemůžou mít lokální proměnné podle odkazu.
-
- Odkaz vrácený voláním funkce {0} nelze zachovat v rámci hranice await nebo yield.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
index 5bf51a1f40385..d91808e6fc8ff 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
@@ -267,14 +267,14 @@
Das Datensatzelement "{0}" muss eine lesbare Instanzeigenschaft oder ein Feld vom Typ "{1}" sein, um dem Positionsparameter "{2}" zu entsprechen.
-
-
- A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions.
+
+
+ foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct.
-
-
- Eine using-Anweisungsressource vom Typ „{0}“ kann nicht in asynchronen Methoden oder asynchronen Lambdaausdrücken verwendet werden.
+
+
+ Parameters of type '{0}' cannot be declared in async methods or async lambda expressions.
@@ -1712,6 +1712,11 @@
Ein Verweisfeld kann nur in einer Verweisstruktur deklariert werden.
+
+
+ A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+
+ Die linke Seite einer Ref-Zuweisung muss eine Ref-Variable sein.
@@ -2347,6 +2352,11 @@
ref readonly-Parameter
+
+
+ ref and unsafe in async and iterator methods
+
+ entspannter Schichtoperator
@@ -10540,8 +10550,8 @@ Unterstützen Sie den Compiler bei der Unterscheidung zwischen den Methoden. Daz
-
- '"await" kann nicht in einem Ausdruck verwendet werden, der den Typ "{0}" enthält
+
+ '"await" kann nicht in einem Ausdruck verwendet werden, der den Typ "{0}" enthält
@@ -10609,16 +10619,6 @@ Unterstützen Sie den Compiler bei der Unterscheidung zwischen den Methoden. Daz
Der Modifizierer "async" kann nur in Methoden verwendet werden, die über einen Textkörper verfügen.
-
-
- Parameter oder lokale Variablen des Typs "{0}" können nicht in asynchronen Methoden oder in asynchronen Lambdaausdrücken deklariert werden.
-
-
-
-
- Die foreach-Anweisung kann nicht für Enumeratoren vom Typ "{0}" in asynchronen oder Iteratormethoden verwendet werden, weil "{0}" eine Referenzstruktur ist.
-
- Das Sicherheitsattribut "{0}" kann nicht auf eine Async-Methode angewendet werden.
@@ -11138,7 +11138,7 @@ Sie sollten das Unterdrücken der Warnung nur in Betracht ziehen, wenn Sie siche
- Eine Instanz des Typs "{0}" kann nicht in einer geschachtelten Funktion, einem Abfrageausdruck, einem Iteratorblock oder einer Async-Methode verwendet werden.
+ Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method
@@ -12449,16 +12449,6 @@ Um die Warnung zu beheben, können Sie stattdessen /reference verwenden (Einbett
Der lokale Verweis "{0}" kann nicht in einer anonymen Methode, einem Lambdaausdruck oder einem Abfrageausdruck verwendet werden.
-
-
- Iteratoren dürfen keine lokalen by-reference-Elemente aufweisen.
-
-
-
-
- Asynchrone Methoden dürfen keine lokalen by-reference-Elemente aufweisen.
-
- Ein Verweis, der von einem Aufruf von "{0}" zurückgegeben wird, kann nicht über die Grenzen "await" oder "yield" hinweg beibehalten werden.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
index 169002cf621a1..519a716d29c04 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
@@ -267,14 +267,14 @@
El miembro de registro '{0}' debe ser una propiedad de instancia legible o un campo de tipo '{1}' para coincidir con el parámetro posicional '{2}'.
-
-
- A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions.
+
+
+ foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct.
-
-
- Un recurso de instrucción using de tipo '{0}' no se puede usar en métodos asincrónicos ni expresiones lambda asincrónicas.
+
+
+ Parameters of type '{0}' cannot be declared in async methods or async lambda expressions.
@@ -1712,6 +1712,11 @@
Un campo ref solo se puede declarar en una estructura ref.
+
+
+ A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+
+ La parte izquierda de una asignación de referencias debe ser una variable local.
@@ -2347,6 +2352,11 @@
parámetros ref readonly
+
+
+ ref and unsafe in async and iterator methods
+
+ operador de cambios relajado
@@ -10540,8 +10550,8 @@ Indique al compilador alguna forma de diferenciar los métodos. Por ejemplo, pue
-
- 'await' no se puede usar en una expresión que contenga el tipo '{0}'
+
+ 'await' no se puede usar en una expresión que contenga el tipo '{0}'
@@ -10609,16 +10619,6 @@ Indique al compilador alguna forma de diferenciar los métodos. Por ejemplo, pue
El modificador 'async' solo se puede usar en métodos que tengan un cuerpo.
-
-
- Los parámetros o locales de tipo '{0}' no pueden declararse en expresiones lambda o métodos asincrónicos.
-
-
-
-
- La instrucción foreach no puede funcionar en enumeradores de tipo "{0}" en métodos async o iterator porque "{0}" es una estructura ref.
-
- El atributo de seguridad '{0}' no se puede aplicar a un método Async.
@@ -11138,7 +11138,7 @@ Considere la posibilidad de suprimir la advertencia solo si tiene la seguridad d
- La instancia de tipo "{0}" no se puede usar dentro de una función anidada, una expresión de consulta, un bloque iterador ni un método asincrónico.
+ Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method
@@ -12449,16 +12449,6 @@ Para eliminar la advertencia puede usar /reference (establezca la propiedad Embe
No se puede usar la variable local de tipo ref '{0}' dentro de un método anónimo, una expresión lambda o una expresión de consulta.
-
-
- Los iteradores no pueden tener variables locales por referencia.
-
-
-
-
- Los métodos asincrónicos no pueden tener variables locales por referencia.
-
- Una referencia devuelta por una llamada a '{0}' no se puede conservar a través del límite "await" o "yield".
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
index 127c92447318d..ceb81446301bf 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
@@ -267,14 +267,14 @@
Le membre d'enregistrement '{0}' doit être une propriété d'instance our champ lisible de type '{1}' pour correspondre au paramètre positionnel '{2}'.
-
-
- A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions.
+
+
+ foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct.
-
-
- Une ressource d’instruction d’utilisation de type '{0}' ne peut pas être utilisée dans des méthodes asynchrones ou des expressions lambda asynchrones.
+
+
+ Parameters of type '{0}' cannot be declared in async methods or async lambda expressions.
@@ -1712,6 +1712,11 @@
Un champ de référence ne peut être déclaré que dans une sructure de référence.
+
+
+ A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+
+ Le côté gauche d’une affectation ref doit être une variable ref.
@@ -2347,6 +2352,11 @@
paramètres ref readonly
+
+
+ ref and unsafe in async and iterator methods
+
+ opérateur shift souple
@@ -10540,8 +10550,8 @@ Permettez au compilateur de différencier les méthodes. Par exemple, vous pouve
-
- 'await' ne peut pas être utilisé dans une expression contenant le type '{0}'
+
+ 'await' ne peut pas être utilisé dans une expression contenant le type '{0}'
@@ -10609,16 +10619,6 @@ Permettez au compilateur de différencier les méthodes. Par exemple, vous pouve
Le modificateur 'async' ne peut être utilisé que dans des méthodes ayant un corps.
-
-
- Les paramètres ou variables locales de type '{0}' ne peuvent pas être déclarés dans des méthodes asynchrones ou des expressions asynchrones lambda.
-
-
-
-
- L'instruction foreach ne peut pas fonctionner sur les énumérateurs de type '{0}' dans les méthodes asynchrones ou les méthodes d'itérateurs, car '{0}' est un struct par référence.
-
- Impossible d'appliquer l'attribut de sécurité '{0}' à une méthode Async.
@@ -11138,7 +11138,7 @@ Supprimez l'avertissement seulement si vous êtes sûr de ne pas vouloir attendr
- Impossible d'utiliser une instance de type '{0}' dans une fonction imbriquée, une expression de requête, un bloc itérateur ou une méthode async
+ Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method
@@ -12449,16 +12449,6 @@ Pour supprimer l'avertissement, vous pouvez utiliser la commande /reference (dé
Impossible d'utiliser ref local '{0}' dans une méthode anonyme, une expression lambda ou une expression de requête
-
-
- Les itérateurs ne peuvent pas avoir de variables locales par référence
-
-
-
-
- Les méthodes async ne peuvent pas avoir de variables locales par référence
-
- Une référence renvoyée par un appel à '{0}' ne peut pas être conservée à travers la limite 'wait' ou 'yield'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
index af24bf98301b5..f1568d3b31829 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
@@ -267,14 +267,14 @@
Il membro di record '{0}' deve essere una proprietà di istanza leggibile o campo di tipo '{1}' per corrispondere al parametro posizionale '{2}'.
-
-
- A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions.
+
+
+ foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct.
-
-
- Non è possibile usare una risorsa di istruzione using di tipo '{0}' in metodi asincroni o espressioni lambda asincrone.
+
+
+ Parameters of type '{0}' cannot be declared in async methods or async lambda expressions.
@@ -1712,6 +1712,11 @@
Un campo ref può essere dichiarato solo in uno struct ref.
+
+
+ A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+
+ La parte sinistra di un'assegnazione ref deve essere una variabile ref.
@@ -2347,6 +2352,11 @@
parametri di sola lettura ref
+
+
+ ref and unsafe in async and iterator methods
+
+ operatore di spostamento rilassato
@@ -10540,8 +10550,8 @@ Impostare il compilatore in modo tale da distinguere i metodi, ad esempio assegn
-
- 'non è possibile usare 'await' in un'espressione contenente il tipo '{0}'
+
+ 'non è possibile usare 'await' in un'espressione contenente il tipo '{0}'
@@ -10609,16 +10619,6 @@ Impostare il compilatore in modo tale da distinguere i metodi, ad esempio assegn
Il modificatore 'async' può essere usato solo nei metodi con un corpo.
-
-
- Non è possibile dichiarare parametri o variabili locali di tipo '{0}' in metodi asincroni o espressioni lambda asincrone.
-
-
-
-
- L'istruzione foreach non può funzionare con enumeratori di tipo '{0}' in metodi async o iterator perché '{0}' è uno struct ref.
-
- Non è possibile applicare l'attributo di sicurezza '{0}' a un metodo Async
@@ -11138,7 +11138,7 @@ Come procedura consigliata, è consigliabile attendere sempre la chiamata.
- L'istanza di tipo '{0}' non può essere usata all'interno di una funzione annidata, un'espressione di query, un blocco iteratore o un metodo asincrono
+ Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method
@@ -12449,16 +12449,6 @@ Per rimuovere l'avviso, è invece possibile usare /reference (impostare la propr
Non è possibile usare la variabile locale ref '{0}' in un metodo anonimo, in un'espressione lambda o in un'espressione di query
-
-
- Gli iteratori non possono includere variabili locali per riferimento
-
-
-
-
- I metodi Async non possono includere variabili locali per riferimento
-
- Non è possibile mantenere un riferimento restituito da una chiamata a '{0}' oltre il limite 'await' o 'yield'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
index 0f77641625862..e98478c3c0f65 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
@@ -267,14 +267,14 @@
レコード メンバー '{0}' は、位置指定パラメーター '{2}' に一致させるための型 '{1}' の読み取り可能なインスタンス プロパティまたはフィールドである必要があります。
-
-
- A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions.
+
+
+ foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct.
-
-
- 型 '{0}' の using ステートメント リソースは、非同期メソッドまたは非同期ラムダ式では使用できません。
+
+
+ Parameters of type '{0}' cannot be declared in async methods or async lambda expressions.
@@ -1712,6 +1712,11 @@
ref フィールドは ref 構造体でのみ宣言できます。
+
+
+ A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+
+ ref 代入の左辺は ref 変数である必要があります。
@@ -2347,6 +2352,11 @@
ref readonly パラメーター
+
+
+ ref and unsafe in async and iterator methods
+
+ 緩和されたシフト演算子
@@ -10540,8 +10550,8 @@ C# では out と ref を区別しますが、CLR では同じと認識します
-
- 'await' は、型 '{0}' を含む式では使用できません
+
+ 'await' は、型 '{0}' を含む式では使用できません
@@ -10609,16 +10619,6 @@ C# では out と ref を区別しますが、CLR では同じと認識します
async' 修飾子は、本体があるメソッドでのみ使用できます。
-
-
- '{0}' 型のパラメーターまたはローカルは、非同期メソッドまたは非同期ラムダ式で宣言することができません。
-
-
-
-
- '{0}' は ref 構造体であるため、非同期または反復子のメソッド内で型 '{0}' の列挙子に対して foreach ステートメントは機能しません。
-
- セキュリティ属性 '{0}' を非同期メソッドに適用することはできません。
@@ -11138,7 +11138,7 @@ You should consider suppressing the warning only if you're sure that you don't w
- 型 '{0}' のインスタンスは、入れ子になった関数、クエリ式、反復子ブロック、または非同期メソッドの中では使用できません
+ Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method
@@ -12449,16 +12449,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
匿名メソッド、ラムダ式、クエリ式内で ref ローカル変数 '{0}' は使用できません
-
-
- 反復子は参照渡しのローカル変数を持つことができません
-
-
-
-
- 非同期メソッドは参照渡しのローカル変数を持つことができません
-
- '{0}' への呼び出しによって返された参照は、'await' または 'yield' 境界を越えて保持することはできません。
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
index fd7b9c8c83b4d..7e87768b4bf62 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
@@ -267,14 +267,14 @@
위치 매개 변수 '{0}'과(와) 일치하려면 레코드 멤버 '{1}'이(가) 유형 '{2}'의 읽을 수 있는 인스턴스 속성 또는 필드여야 합니다.
-
-
- A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions.
+
+
+ foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct.
-
-
- '{0}' 형식의 using 문 리소스는 비동기 메서드 또는 비동기 람다 식에 사용할 수 없습니다.
+
+
+ Parameters of type '{0}' cannot be declared in async methods or async lambda expressions.
@@ -1712,6 +1712,11 @@
ref 필드는 ref 구조체에서만 선언할 수 있습니다.
+
+
+ A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+
+ ref 할당의 왼쪽은 ref 변수여야 합니다.
@@ -2347,6 +2352,11 @@
ref readonly 매개 변수
+
+
+ ref and unsafe in async and iterator methods
+
+ 완화된 시프트 연산자
@@ -10540,8 +10550,8 @@ C#에서는 out과 ref를 구분하지만 CLR에서는 동일한 것으로 간
-
- 'await'는 '{0}' 형식이 포함된 식에 사용할 수 없습니다.
+
+ 'await'는 '{0}' 형식이 포함된 식에 사용할 수 없습니다.
@@ -10609,16 +10619,6 @@ C#에서는 out과 ref를 구분하지만 CLR에서는 동일한 것으로 간
async' 한정자는 본문이 있는 메서드에서만 사용할 수 있습니다.
-
-
- '{0}' 형식의 매개 변수 또는 로컬은 비동기 메서드나 비동기 람다 식에서 선언할 수 없습니다.
-
-
-
-
- '{0}'은(는) ref struct이므로 비동기 또는 반복기 메서드의 '{0}' 형식 열거자에서 foreach 문을 수행할 수 없습니다.
-
- '{0}' 보안 특성은 비동기 메서드에 적용할 수 없습니다.
@@ -11138,7 +11138,7 @@ You should consider suppressing the warning only if you're sure that you don't w
- '{0}' 형식의 인스턴스는 중첩된 함수, 쿼리 식, 반복기 블록 또는 비동기 메서드 내에서 사용할 수 없습니다.
+ Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method
@@ -12449,16 +12449,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
무명 메서드, 람다 식 또는 쿼리 식에는 참조 로컬 '{0}'을(를) 사용할 수 없습니다.
-
-
- 반복기에 by-reference 로컬을 사용할 수 없습니다.
-
-
-
-
- 비동기 메서드에 by-reference 로컬을 사용할 수 없습니다.
-
- '{0}'에 대한 호출로 반환된 참조는 'await' 또는 'yield' 경계에서 보존할 수 없습니다.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
index 4092f9b5e67c5..7dcc59fdbd7f6 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
@@ -267,14 +267,14 @@
Składowa rekordu "{0}" musi być możliwą do odczytu właściwością wystąpienia typu "{1}", aby dopasować parametr pozycyjny "{2}".
-
-
- A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions.
+
+
+ foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct.
-
-
- Zasobu instrukcji przy użyciu typu '{0}' nie można używać w metodach asynchronicznych ani asynchronicznych wyrażeniach lambda.
+
+
+ Parameters of type '{0}' cannot be declared in async methods or async lambda expressions.
@@ -1712,6 +1712,11 @@
Pole referencyjne można zadeklarować tylko w strukturze referencyjnej.
+
+
+ A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+
+ Lewa strona przypisania referencyjnego musi być zmienną referencyjną.
@@ -2347,6 +2352,11 @@
parametry tylko do odczytu ref
+
+
+ ref and unsafe in async and iterator methods
+
+ operator swobodnej zmiany
@@ -10540,8 +10550,8 @@ Musisz umożliwić kompilatorowi rozróżnienie metod. Możesz na przykład nada
-
- 'Operatora „await” nie można użyć w wyrażeniu zawierającym typ „{0}”
+
+ 'Operatora „await” nie można użyć w wyrażeniu zawierającym typ „{0}”
@@ -10609,16 +10619,6 @@ Musisz umożliwić kompilatorowi rozróżnienie metod. Możesz na przykład nada
Modyfikatora „async” można używać tylko w metodach mających treść.
-
-
- Parametrów ani elementów lokalnych typu „{0}” nie można deklarować w metodach asynchronicznych ani wyrażeniach lambda.
-
-
-
-
- Instrukcja foreach nie może działać na modułach wyliczających typu „{0}” w metodach asynchronicznych lub iteratora, ponieważ element „{0}” jest strukturą ref.
-
- Atrybutu zabezpieczeń „{0}” nie można zastosować dla metody asynchronicznej.
@@ -11138,7 +11138,7 @@ Pominięcie ostrzeżenia należy wziąć pod uwagę tylko w sytuacji, gdy na pew
- Wystąpienia typu „{0}” nie można użyć wewnątrz funkcji zagnieżdżonej, wyrażenia zapytania, bloku iteratora ani metody asynchronicznej
+ Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method
@@ -12449,16 +12449,6 @@ Aby usunąć ostrzeżenie, możesz zamiast tego użyć opcji /reference (ustaw w
Nie można użyć zmiennej lokalnej typu ref „{0}” wewnątrz metody anonimowej, wyrażenia lambda ani wyrażenia zapytania
-
-
- Iteratory nie mogą mieć zmiennych lokalnych dostępnych przez odwołanie
-
-
-
-
- Metody asynchroniczne nie mogą mieć zmiennych lokalnych dostępnych przez odwołanie
-
- Odwołanie zwrócone przez wywołanie „{0}” nie może zostać zachowane w granicach „await” lub „yield”.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
index 06cd639492e03..578dd52d42e00 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
@@ -267,14 +267,14 @@
O membro do registro '{0}' precisa ser uma propriedade de instância legível ou campo do tipo '{1}' para corresponder ao parâmetro posicional '{2}'.
-
-
- A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions.
+
+
+ foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct.
-
-
- Um recurso de instrução using do tipo "{0}" não pode ser usado em métodos assíncronos ou expressões lambda assíncronas.
+
+
+ Parameters of type '{0}' cannot be declared in async methods or async lambda expressions.
@@ -1712,6 +1712,11 @@
Um campo ref só pode ser declarado em uma estrutura ref.
+
+
+ A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+
+ O lado esquerdo de uma atribuição ref deve ser uma variável ref.
@@ -2347,6 +2352,11 @@
parâmetros ref readonly
+
+
+ ref and unsafe in async and iterator methods
+
+ operador de deslocamento flexível
@@ -10540,8 +10550,8 @@ Forneça ao compilador alguma forma de diferenciar os métodos. Por exemplo, voc
-
- 'aguardar' não pode ser usado em uma expressão que contém o tipo '{0}'
+
+ 'aguardar' não pode ser usado em uma expressão que contém o tipo '{0}'
@@ -10609,16 +10619,6 @@ Forneça ao compilador alguma forma de diferenciar os métodos. Por exemplo, voc
O modificador 'async' só pode ser usado em métodos que têm um corpo.
-
-
- Os parâmetros ou locais do tipo '{0}' não podem ser declarados nos métodos async ou expressões async lambda.
-
-
-
-
- a instrução foreach não pode operar em enumeradores do tipo '{0}' em métodos assíncronos ou iteradores porque '{0}' é uma struct de referência.
-
- Atributo de segurança "{0}" não pode ser aplicado a um método Assíncrono.
@@ -11138,7 +11138,7 @@ Você pode suprimir o aviso se tiver certeza de que não vai querer aguardar a c
- A instância do tipo '{0}' não pode ser usada dentro de uma função aninhada, expressão de consulta, bloco de iteradores ou método assíncrono
+ Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method
@@ -12449,16 +12449,6 @@ Para incorporar informações de tipo de interoperabilidade para os dois assembl
Não é possível usar a referência local '{0}' em um método anônimo, expressão lambda ou expressão de consulta
-
-
- Os iteradores não podem ter locais por referência
-
-
-
-
- Os métodos assíncronos não podem ter locais por referência
-
- Uma referência retornada por uma chamada para '{0}' não pode ser preservada no limite 'await' ou 'yield'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
index 954057392e614..619ac7320a17b 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
@@ -267,14 +267,14 @@
Элемент записи "{0}" должен быть доступным для чтения свойством экземпляра или полем типа "{1}", чтобы соответствовать позиционному параметру "{2}".
-
-
- A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions.
+
+
+ foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct.
-
-
- Ресурс оператора использования типа "{0}" нельзя применять в асинхронных методах или асинхронных лямбда-выражениях.
+
+
+ Parameters of type '{0}' cannot be declared in async methods or async lambda expressions.
@@ -1712,6 +1712,11 @@
Поле ссылки может быть объявлено только в структуре ссылки.
+
+
+ A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+
+ Левая сторона назначения ref должна быть переменной ref.
@@ -2347,6 +2352,11 @@
Параметры ref, доступные только для чтения
+
+
+ ref and unsafe in async and iterator methods
+
+ нестрогий оператор сдвига
@@ -10541,8 +10551,8 @@ Give the compiler some way to differentiate the methods. For example, you can gi
-
- '"await" нельзя использовать в выражении, содержащем тип "{0}"
+
+ '"await" нельзя использовать в выражении, содержащем тип "{0}"
@@ -10610,16 +10620,6 @@ Give the compiler some way to differentiate the methods. For example, you can gi
Модификатор "async" можно использовать только в методах, имеющих тело.
-
-
- Параметры или локальные переменные типа "{0}" не могут объявляться в асинхронных методах и в асинхронных лямбда-выражениях.
-
-
-
-
- Оператор foreach нельзя использовать с перечислителями типа "{0}" в методах с модификатором Async или Iterator, так как "{0}" является ссылочной структурой.
-
- Атрибут безопасности "{0}" нельзя применить к асинхронному методу.
@@ -11139,7 +11139,7 @@ You should consider suppressing the warning only if you're sure that you don't w
- Экземпляр типа "{0}" нельзя использовать внутри вложенной функции, выражения запроса, блока итератора или асинхронного метода.
+ Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method
@@ -12450,16 +12450,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
Невозможно использовать локальную переменную ref "{0}" внутри анонимного метода, лямбда-выражения или выражения запроса
-
-
- Итераторы не могут иметь локальных переменных по ссылке
-
-
-
-
- Асинхронные методы не могут иметь локальных переменных по ссылке
-
- Ссылка, возвращенная вызовом ' {0} ', не может быть сохранена за границей 'wait' или 'yield'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
index a44ca7bfed87c..981f7741495aa 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
@@ -267,14 +267,14 @@
{0} kayıt üyesi, {1} konumsal parametresi ile eşleşmesi için {2} türünde okunabilir bir örnek özelliği veya alan olmalıdır.
-
-
- A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions.
+
+
+ foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct.
-
-
- '{0}' türündeki bir using deyimi kaynağı, asenkron yöntemlerde veya asenkron lambda ifadelerinde kullanılamaz.
+
+
+ Parameters of type '{0}' cannot be declared in async methods or async lambda expressions.
@@ -1712,6 +1712,11 @@
Başvuru alanı yalnızca başvuru yapısında bildirilebilir.
+
+
+ A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+
+ ref atamasının sol tarafı, ref değişkeni olmalıdır.
@@ -2347,6 +2352,11 @@
ref salt okunur parametreleri
+
+
+ ref and unsafe in async and iterator methods
+
+ esnek kaydırma işleci
@@ -10540,8 +10550,8 @@ Derleyiciye yöntemleri ayrıştırma yolu verin. Örneğin, bunlara farklı adl
-
- 'await', '{0}' türünü içeren bir ifadede kullanılamaz
+
+ 'await', '{0}' türünü içeren bir ifadede kullanılamaz
@@ -10609,16 +10619,6 @@ Derleyiciye yöntemleri ayrıştırma yolu verin. Örneğin, bunlara farklı adl
Async' değiştiricisi yalnızca gövdesi olan metotlarda kullanılabilir.
-
-
- Zaman uyumsuz yöntemlerde veya zaman uyumsuz lambda ifadelerinde '{0}' türündeki parametreler veya yerel öğeler bildirilemez.
-
-
-
-
- '{0}' bir başvuru yapısı olduğundan foreach deyimi, async veya iterator metotlarındaki '{0}' türü numaralandırıcılar üzerinde çalışamaz.
-
- '{0}' güvenlik özniteliği bir Async yöntemine uygulanamaz.
@@ -11138,7 +11138,7 @@ Yalnızca asenkron çağrının tamamlanmasını beklemek istemediğinizden ve
- '{0}' türünün örneği iç içe geçmiş bir işlevde, sorgu ifadesinde, yineleyici bloğunda veya zaman uyumsuz bir metotta kullanılamaz
+ Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method
@@ -12449,16 +12449,6 @@ Uyarıyı kaldırmak için, /reference kullanabilirsiniz (Birlikte Çalışma T
'{0}' ref yerel değeri bir anonim metotta, lambda ifadesinde veya sorgu ifadesinde kullanılamaz
-
-
- Yineleyiciler başvuruya göre yerel değerlere sahip olamaz
-
-
-
-
- Zaman uyumsuz metotlar başvuruya göre yerel değerlere sahip olamaz
-
- '{0}' hedefine bir çağrı tarafından döndürülen başvuru, 'await' veya 'yield' sınırında korunamıyor.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
index 3c164338d3da3..5aceeb57b426c 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
@@ -267,14 +267,14 @@
记录成员 '{0}' 必须为类型 '{1}' 的可读实例属性或字段,以匹配位置参数 '{2}'。
-
-
- A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions.
+
+
+ foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct.
-
-
- 无法在异步方法或异步 lambda 表达式中使用类型为“{0}”的 using 语句资源。
+
+
+ Parameters of type '{0}' cannot be declared in async methods or async lambda expressions.
@@ -1712,6 +1712,11 @@
ref 字段只能在 ref 结构中声明。
+
+
+ A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+
+ ref 赋值的左侧必须为 ref 变量。
@@ -2347,6 +2352,11 @@
ref readonly 参数
+
+
+ ref and unsafe in async and iterator methods
+
+ 移位运算符
@@ -10540,8 +10550,8 @@ Give the compiler some way to differentiate the methods. For example, you can gi
-
- '“等待”不能在包含“{0}”类型的表达式中使用
+
+ '“等待”不能在包含“{0}”类型的表达式中使用
@@ -10609,16 +10619,6 @@ Give the compiler some way to differentiate the methods. For example, you can gi
只能在具有正文的方法中使用 "async" 修饰符。
-
-
- 不能在异步方法或异步 lambda 表达式中声明类型“{0}”的参数或局部变量。
-
-
-
-
- foreach 语句无法在类型“{0}”的枚举器上使用异步或迭代器方法操作,因为“{0}”是 ref 结构。
-
- 安全特性“{0}”不可应用于异步方法。
@@ -11138,7 +11138,7 @@ You should consider suppressing the warning only if you're sure that you don't w
- “{0}”类型的实例不能在嵌套函数、查询表达式、迭代器块或异步方法中使用
+ Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method
@@ -12449,16 +12449,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
不能在匿名方法、lambda 表达式或查询表达式内使用 ref 局部变量“{0}”
-
-
- 迭代器不能有按引用局部变量
-
-
-
-
- 异步方法不能有按引用局部变量
-
- 调用“{0}”所返回的引用不能跨 "await" 或 "yield" 边界保留。
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
index 30d0776683b21..3b36564d36e33 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
@@ -267,14 +267,14 @@
記錄成員 '{0}' 必須是類型 '{1}' 的可讀取執行個體屬性或欄位,才能符合位置參數 '{2}'。
-
-
- A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions.
+
+
+ foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct.
-
-
- 類型 '{0}' 的 using 陳述式資源不能用於非同步方法或非同步 Lambda 運算式。
+
+
+ Parameters of type '{0}' cannot be declared in async methods or async lambda expressions.
@@ -1712,6 +1712,11 @@
ref 欄位只能在 ref 結構中宣告。
+
+
+ A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+
+ 參考指派的左側必須為 ref 變數。
@@ -2347,6 +2352,11 @@
ref readonly 參數
+
+
+ ref and unsafe in async and iterator methods
+
+ 寬鬆移位 (Shift) 運算子
@@ -10540,8 +10550,8 @@ Give the compiler some way to differentiate the methods. For example, you can gi
-
- 'await' 不得用於包含類型 '{0}' 的運算式中
+
+ 'await' 不得用於包含類型 '{0}' 的運算式中
@@ -10609,16 +10619,6 @@ Give the compiler some way to differentiate the methods. For example, you can gi
async' 修飾元只可用於具有主體的方法。
-
-
- 類型 '{0}' 的參數或區域變數,不可在非同步方法或非同步 Lambda 運算式中宣告。
-
-
-
-
- foreach 陳述式無法對 async 或 iterator 方法中類型 '{0}' 的列舉值進行操作,因為 '{0}' 為 ref struct。
-
- 安全屬性 '{0}' 無法套用至非同步方法。
@@ -11138,7 +11138,7 @@ You should consider suppressing the warning only if you're sure that you don't w
- 類型 '{0}' 的執行個體不可用於巢狀函式、查詢運算式、迭代區塊或非同步方法中
+ Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method
@@ -12449,16 +12449,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
無法在匿名方法、Lambda 運算式或查詢運算式中使用參考本機 '{0}'
-
-
- Iterator 不可有 by-reference local
-
-
-
-
- 非同步方法不可有 by-reference local
-
- 對 '{0}' 之呼叫所傳回的參考無法在 'await' 或 'yield' 界限間保留。
diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs
index 778817985654a..da3d964d5a24a 100644
--- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs
@@ -133,7 +133,7 @@ private static void VerifyMissingType(string source, WellKnownType type, params
// Instrumentation to investigate CI failure: https://github.com/dotnet/roslyn/issues/34207
private CSharpCompilation CreateCompilationWithAsyncIterator(string source, CSharpCompilationOptions options = null, CSharpParseOptions parseOptions = null)
=> CreateCompilationWithTasksExtensions(new[] { (CSharpTestSource)CSharpTestBase.Parse(source, filename: "source", parseOptions), CSharpTestBase.Parse(AsyncStreamsTypes, filename: "AsyncStreamsTypes", parseOptions) },
- options: options, parseOptions: parseOptions);
+ options: options);
private CSharpCompilation CreateCompilationWithAsyncIterator(CSharpTestSource source, CSharpCompilationOptions options = null, CSharpParseOptions parseOptions = null)
=> CreateCompilationWithTasksExtensions(new[] { source, AsyncStreamsTypes }, options: options, parseOptions: parseOptions);
@@ -631,15 +631,288 @@ static async System.Threading.Tasks.Task Main()
ref struct S
{
}";
+
+ var expectedDiagnostics = new[]
+ {
+ // source(4,65): error CS0306: The type 'S' may not be used as a type argument
+ // static async System.Collections.Generic.IAsyncEnumerable M()
+ Diagnostic(ErrorCode.ERR_BadTypeArgument, "M").WithArguments("S").WithLocation(4, 65)
+ };
+
var comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe);
+ comp.VerifyDiagnostics(expectedDiagnostics);
+
+ comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe, parseOptions: TestOptions.RegularNext);
+ comp.VerifyDiagnostics(expectedDiagnostics);
+
+ comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular12);
comp.VerifyDiagnostics(
// source(4,65): error CS0306: The type 'S' may not be used as a type argument
// static async System.Collections.Generic.IAsyncEnumerable M()
Diagnostic(ErrorCode.ERR_BadTypeArgument, "M").WithArguments("S").WithLocation(4, 65),
- // source(11,24): error CS4012: Parameters or locals of type 'S' cannot be declared in async methods or async lambda expressions.
+ // source(11,24): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// await foreach (var s in M())
- Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "var").WithArguments("S").WithLocation(11, 24)
- );
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(11, 24));
+ }
+
+ [Fact]
+ public void RefStructElementType_NonGeneric()
+ {
+ string source = """
+ using System.Threading.Tasks;
+
+ class C
+ {
+ public E GetAsyncEnumerator() => new E();
+ static async Task Main()
+ {
+ await foreach (var s in new C())
+ {
+ System.Console.Write(s.F);
+ }
+ }
+ }
+ class E
+ {
+ bool _done;
+ public S Current => new S { F = 123 };
+ public async Task MoveNextAsync()
+ {
+ await Task.Yield();
+ return !_done ? (_done = true) : false;
+ }
+ }
+ ref struct S
+ {
+ public int F;
+ }
+ """;
+
+ var comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular12);
+ comp.VerifyDiagnostics(
+ // source(8,24): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // await foreach (var s in new C())
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 24));
+
+ comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe, parseOptions: TestOptions.RegularNext);
+ comp.VerifyEmitDiagnostics();
+
+ comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe);
+ var verifier = CompileAndVerify(comp, expectedOutput: "123", verify: Verification.FailsILVerify);
+ verifier.VerifyDiagnostics();
+ verifier.VerifyIL("C.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """
+ {
+ // Code size 238 (0xee)
+ .maxstack 3
+ .locals init (int V_0,
+ S V_1, //s
+ System.Runtime.CompilerServices.TaskAwaiter V_2,
+ C.d__1 V_3,
+ System.Exception V_4)
+ IL_0000: ldarg.0
+ IL_0001: ldfld "int C.d__1.<>1__state"
+ IL_0006: stloc.0
+ .try
+ {
+ IL_0007: ldloc.0
+ IL_0008: brfalse.s IL_0012
+ IL_000a: br.s IL_000c
+ IL_000c: ldloc.0
+ IL_000d: ldc.i4.1
+ IL_000e: beq.s IL_0014
+ IL_0010: br.s IL_0016
+ IL_0012: br.s IL_0082
+ IL_0014: br.s IL_0082
+ IL_0016: nop
+ IL_0017: nop
+ IL_0018: ldarg.0
+ IL_0019: newobj "C..ctor()"
+ IL_001e: call "E C.GetAsyncEnumerator()"
+ IL_0023: stfld "E C.d__1.<>s__1"
+ IL_0028: br.s IL_0044
+ IL_002a: ldarg.0
+ IL_002b: ldfld "E C.d__1.<>s__1"
+ IL_0030: callvirt "S E.Current.get"
+ IL_0035: stloc.1
+ IL_0036: nop
+ IL_0037: ldloc.1
+ IL_0038: ldfld "int S.F"
+ IL_003d: call "void System.Console.Write(int)"
+ IL_0042: nop
+ IL_0043: nop
+ IL_0044: ldarg.0
+ IL_0045: ldfld "E C.d__1.<>s__1"
+ IL_004a: callvirt "System.Threading.Tasks.Task E.MoveNextAsync()"
+ IL_004f: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"
+ IL_0054: stloc.2
+ IL_0055: ldloca.s V_2
+ IL_0057: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"
+ IL_005c: brtrue.s IL_009e
+ IL_005e: ldarg.0
+ IL_005f: ldc.i4.0
+ IL_0060: dup
+ IL_0061: stloc.0
+ IL_0062: stfld "int C.d__1.<>1__state"
+ IL_0067: ldarg.0
+ IL_0068: ldloc.2
+ IL_0069: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__1"
+ IL_006e: ldarg.0
+ IL_006f: stloc.3
+ IL_0070: ldarg.0
+ IL_0071: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"
+ IL_0076: ldloca.s V_2
+ IL_0078: ldloca.s V_3
+ IL_007a: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__1)"
+ IL_007f: nop
+ IL_0080: leave.s IL_00ed
+ IL_0082: ldarg.0
+ IL_0083: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__1"
+ IL_0088: stloc.2
+ IL_0089: ldarg.0
+ IL_008a: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__1"
+ IL_008f: initobj "System.Runtime.CompilerServices.TaskAwaiter"
+ IL_0095: ldarg.0
+ IL_0096: ldc.i4.m1
+ IL_0097: dup
+ IL_0098: stloc.0
+ IL_0099: stfld "int C.d__1.<>1__state"
+ IL_009e: ldarg.0
+ IL_009f: ldloca.s V_2
+ IL_00a1: call "bool System.Runtime.CompilerServices.TaskAwaiter.GetResult()"
+ IL_00a6: stfld "bool C.d__1.<>s__2"
+ IL_00ab: ldarg.0
+ IL_00ac: ldfld "bool C.d__1.<>s__2"
+ IL_00b1: brtrue IL_002a
+ IL_00b6: ldarg.0
+ IL_00b7: ldnull
+ IL_00b8: stfld "E C.d__1.<>s__1"
+ IL_00bd: leave.s IL_00d9
+ }
+ catch System.Exception
+ {
+ IL_00bf: stloc.s V_4
+ IL_00c1: ldarg.0
+ IL_00c2: ldc.i4.s -2
+ IL_00c4: stfld "int C.d__1.<>1__state"
+ IL_00c9: ldarg.0
+ IL_00ca: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"
+ IL_00cf: ldloc.s V_4
+ IL_00d1: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"
+ IL_00d6: nop
+ IL_00d7: leave.s IL_00ed
+ }
+ IL_00d9: ldarg.0
+ IL_00da: ldc.i4.s -2
+ IL_00dc: stfld "int C.d__1.<>1__state"
+ IL_00e1: ldarg.0
+ IL_00e2: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"
+ IL_00e7: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"
+ IL_00ec: nop
+ IL_00ed: ret
+ }
+ """);
+ }
+
+ [Fact]
+ public void RefStructElementType_NonGeneric_AwaitAfter()
+ {
+ string source = """
+ using System.Threading.Tasks;
+
+ class C
+ {
+ public E GetAsyncEnumerator() => new E();
+ static async Task Main()
+ {
+ await foreach (var s in new C())
+ {
+ System.Console.Write(s.F);
+ await Task.Yield();
+ }
+ }
+ }
+ class E
+ {
+ bool _done;
+ public S Current => new S { F = 123 };
+ public async Task MoveNextAsync()
+ {
+ await Task.Yield();
+ return !_done ? (_done = true) : false;
+ }
+ }
+ ref struct S
+ {
+ public int F;
+ }
+ """;
+
+ var comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular12);
+ comp.VerifyDiagnostics(
+ // source(8,24): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // await foreach (var s in new C())
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 24));
+
+ comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe, parseOptions: TestOptions.RegularNext);
+ comp.VerifyEmitDiagnostics();
+
+ comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe);
+ var verifier = CompileAndVerify(comp, expectedOutput: "123", verify: Verification.FailsILVerify);
+ verifier.VerifyDiagnostics();
+ }
+
+ [Fact]
+ public void RefStructElementType_NonGeneric_AwaitBefore()
+ {
+ string source = """
+ using System.Threading.Tasks;
+
+ class C
+ {
+ public E GetAsyncEnumerator() => new E();
+ static async Task Main()
+ {
+ await foreach (var s in new C())
+ {
+ await Task.Yield();
+ System.Console.Write(s.F);
+ }
+ }
+ }
+ class E
+ {
+ bool _done;
+ public S Current => new S { F = 123 };
+ public async Task MoveNextAsync()
+ {
+ await Task.Yield();
+ return !_done ? (_done = true) : false;
+ }
+ }
+ ref struct S
+ {
+ public int F;
+ }
+ """;
+
+ var comp = CreateCompilationWithAsyncIterator(source, parseOptions: TestOptions.Regular12);
+ comp.VerifyDiagnostics(
+ // source(8,24): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // await foreach (var s in new C())
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 24));
+
+ var expectedDiagnostics = new[]
+ {
+ // source(11,34): error CS4007: Instance of type 'S' cannot be preserved across 'await' or 'yield' boundary.
+ // System.Console.Write(s.F);
+ Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s.F").WithArguments("S").WithLocation(11, 34)
+ };
+
+ comp = CreateCompilationWithAsyncIterator(source, parseOptions: TestOptions.RegularNext);
+ comp.VerifyEmitDiagnostics(expectedDiagnostics);
+
+ comp = CreateCompilationWithAsyncIterator(source);
+ comp.VerifyEmitDiagnostics(expectedDiagnostics);
}
[Fact]
diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs
index 0a7f649ff7d64..999bf6667331d 100644
--- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs
@@ -3789,9 +3789,11 @@ static async Task Main()
var comp = CreateCompilationWithMscorlibAndSpan(source, options: options);
comp.VerifyDiagnostics();
comp.VerifyEmitDiagnostics(
- // (9,66): error CS4007: 'await' cannot be used in an expression containing the type 'System.Span'
- // await Async1(F1(), G(F2(), stackalloc int[] { 1, 2, 3 }, await F3()));
- Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "await F3()").WithArguments("System.Span").WithLocation(9, 66)
+ // (8,5): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary.
+ // {
+ Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, @"{
+ await Async1(F1(), G(F2(), stackalloc int[] { 1, 2, 3 }, await F3()));
+ }").WithArguments("System.Span").WithLocation(8, 5)
);
}
}
@@ -3897,16 +3899,16 @@ public ref struct S
public bool P2 => true;
}
";
- CreateCompilation(source, options: TestOptions.DebugDll).VerifyDiagnostics().VerifyEmitDiagnostics(
- // (9,17): error CS4013: Instance of type 'S' cannot be used inside a nested function, query expression, iterator block or async method
- // Q { F: { P1: true } } when await c => r, // error: cached Q.F is alive
- Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "F").WithArguments("S").WithLocation(9, 17)
- );
- CreateCompilation(source, options: TestOptions.ReleaseDll).VerifyDiagnostics().VerifyEmitDiagnostics(
- // (9,17): error CS4013: Instance of type 'S' cannot be used inside a nested function, query expression, iterator block or async method
+
+ var expectedDiagnostics = new[]
+ {
+ // (9,17): error CS4007: Instance of type 'S' cannot be preserved across 'await' or 'yield' boundary.
// Q { F: { P1: true } } when await c => r, // error: cached Q.F is alive
- Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "F").WithArguments("S").WithLocation(9, 17)
- );
+ Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "F").WithArguments("S").WithLocation(9, 17)
+ };
+
+ CreateCompilation(source, options: TestOptions.DebugDll).VerifyDiagnostics().VerifyEmitDiagnostics(expectedDiagnostics);
+ CreateCompilation(source, options: TestOptions.ReleaseDll).VerifyDiagnostics().VerifyEmitDiagnostics(expectedDiagnostics);
}
[Fact]
diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs
index bce2519fce4d0..9a099be01840b 100644
--- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs
@@ -1695,12 +1695,26 @@ public System.Threading.Tasks.Task MoveNextAsync()
=> throw null;
public int Current { get => throw null; }
}
-}";
- var comp = CreateCompilationWithTasksExtensions(source + s_IAsyncEnumerable);
+}" + s_IAsyncEnumerable;
+
+ var comp = CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12);
comp.VerifyDiagnostics(
- // (6,32): error CS8177: Async methods cannot have by-reference locals
+ // (6,32): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// await foreach (ref var i in new C())
- Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "i").WithLocation(6, 32));
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "i").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 32));
+
+ var expectedDiagnostics = new[]
+ {
+ // (6,37): error CS1510: A ref or out value must be an assignable variable
+ // await foreach (ref var i in new C())
+ Diagnostic(ErrorCode.ERR_RefLvalueExpected, "new C()").WithLocation(6, 37)
+ };
+
+ comp = CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.RegularNext);
+ comp.VerifyDiagnostics(expectedDiagnostics);
+
+ comp = CreateCompilationWithTasksExtensions(source);
+ comp.VerifyDiagnostics(expectedDiagnostics);
var tree = comp.SyntaxTrees.Single();
var model = (SyntaxTreeSemanticModel)comp.GetSemanticModel(tree, ignoreAccessibility: false);
@@ -1708,6 +1722,119 @@ public System.Threading.Tasks.Task MoveNextAsync()
Assert.Equal(default, model.GetForEachStatementInfo(foreachSyntax));
}
+ [Theory, CombinatorialData]
+ public void TestWithPattern_Ref_Iterator([CombinatorialValues(" ", "readonly")] string modifier)
+ {
+ var source = $$"""
+ using System;
+ using System.Collections.Generic;
+ using System.Threading.Tasks;
+
+ class C
+ {
+ static async Task Main()
+ {
+ await foreach (int i in F())
+ {
+ Console.Write(i);
+ }
+ }
+
+ static async IAsyncEnumerable F()
+ {
+ await foreach (ref {{modifier}} var i in new C())
+ {
+ yield return i;
+ }
+ }
+
+ public Enumerator GetAsyncEnumerator(System.Threading.CancellationToken token = default) => new();
+
+ public sealed class Enumerator
+ {
+ private readonly int[] _array = [1, 2, 3];
+ private int _index = -1;
+ public Task MoveNextAsync()
+ {
+ if (_index < _array.Length) _index++;
+ return Task.FromResult(_index < _array.Length);
+ }
+ public ref int Current => ref _array[_index];
+ }
+ }
+ """ + AsyncStreamsTypes;
+
+ var comp = CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12);
+ comp.VerifyDiagnostics(
+ // (17,41): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // await foreach (ref readonly var i in new C())
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "i").WithArguments("ref and unsafe in async and iterator methods").WithLocation(17, 41));
+
+ var expectedOutput = "123";
+
+ comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularNext);
+ CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
+
+ comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe);
+ CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics();
+ }
+
+ [Fact]
+ public void TestWithPattern_Ref_Iterator_Used()
+ {
+ var source = """
+ using System.Collections.Generic;
+ using System.Threading.Tasks;
+
+ class C
+ {
+ static async IAsyncEnumerable F()
+ {
+ await foreach (ref var i in new C())
+ {
+ yield return i;
+ M(ref i);
+ }
+ }
+
+ static void M(ref int i) { }
+
+ public Enumerator GetAsyncEnumerator(System.Threading.CancellationToken token = default) => new();
+
+ public sealed class Enumerator
+ {
+ private readonly int[] _array = [1, 2, 3];
+ private int _index = -1;
+ public Task MoveNextAsync()
+ {
+ if (_index < _array.Length) _index++;
+ return Task.FromResult(_index < _array.Length);
+ }
+ public ref int Current => ref _array[_index];
+ }
+ }
+ """ + AsyncStreamsTypes;
+
+ var comp = CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12);
+ comp.VerifyDiagnostics(
+ // (8,32): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // await foreach (ref var i in new C())
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "i").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 32));
+
+ var expectedDiagnostics = new[]
+ {
+ // (11,19): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+ // M(ref i);
+ Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "i").WithLocation(11, 19)
+ };
+
+ comp = CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.RegularNext);
+ comp.VerifyEmitDiagnostics(expectedDiagnostics);
+
+ comp = CreateCompilationWithTasksExtensions(source);
+ comp.VerifyEmitDiagnostics(expectedDiagnostics);
+ }
+
[Fact]
public void TestWithPattern_PointerType()
{
@@ -1934,6 +2061,101 @@ public S(int i)
CompileAndVerify(comp, expectedOutput: "1 2 Done");
}
+ [Fact]
+ public void TestWithPattern_RefStructEnumerator()
+ {
+ var source = """
+ using System.Threading.Tasks;
+ public class C
+ {
+ public static async Task Main()
+ {
+ await foreach (var s in new C())
+ {
+ }
+ }
+ public Enumerator GetAsyncEnumerator() => new Enumerator();
+ public ref struct Enumerator
+ {
+ public int Current => 0;
+ public Task MoveNextAsync() => throw null;
+ }
+ }
+ """;
+
+ var expectedDiagnostics = new[]
+ {
+ // (6,15): error CS8344: foreach statement cannot operate on enumerators of type 'C.Enumerator' in async or iterator methods because 'C.Enumerator' is a ref struct.
+ // await foreach (var s in new C())
+ Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("C.Enumerator").WithLocation(6, 15)
+ };
+
+ CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
+ CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics);
+ CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics);
+ }
+
+ [Fact]
+ public void TestWithPattern_RefStructCurrent()
+ {
+ var source = """
+ using System;
+ using System.Threading.Tasks;
+ public class C
+ {
+ public static async Task Main()
+ {
+ await foreach (var s in new C())
+ {
+ Console.Write($"{s.ToString()} ");
+ }
+ Console.Write("Done");
+ }
+ public Enumerator GetAsyncEnumerator() => new Enumerator();
+ public sealed class Enumerator : IAsyncDisposable
+ {
+ int i = 0;
+ public S Current => new S(i);
+ public async Task MoveNextAsync()
+ {
+ i++;
+ return await Task.FromResult(i < 3);
+ }
+ public async ValueTask DisposeAsync()
+ {
+ await Task.Yield();
+ }
+ }
+ }
+ public ref struct S
+ {
+ int i;
+ public S(int i)
+ {
+ this.i = i;
+ }
+ public override string ToString() => i.ToString();
+ }
+ """ + s_IAsyncEnumerable;
+
+ var expectedDiagnostics = new[]
+ {
+ // (7,24): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // await foreach (var s in new C())
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 24)
+ };
+
+ CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics);
+
+ var expectedOutput = "1 2 Done";
+
+ var comp = CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.RegularNext, options: TestOptions.ReleaseExe);
+ CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics();
+
+ comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe);
+ CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics();
+ }
+
[Fact]
public void TestWithPattern_RefReturningCurrent()
{
diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/InlineArrayTests.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/InlineArrayTests.cs
index 1963a7532e9f2..3c90e1f58fc4f 100644
--- a/src/Compilers/CSharp/Test/Emit2/Semantics/InlineArrayTests.cs
+++ b/src/Compilers/CSharp/Test/Emit2/Semantics/InlineArrayTests.cs
@@ -4691,9 +4691,12 @@ static async Task FromResult(T r)
";
var comp = CreateCompilation(src + Buffer10Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe);
comp.VerifyEmitDiagnostics(
- // (24,22): error CS4007: 'await' cannot be used in an expression containing the type 'System.ReadOnlySpan>'
- // [Get01()][await FromResult(Get02(x))];
- Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "await FromResult(Get02(x))").WithArguments("System.ReadOnlySpan>").WithLocation(24, 22)
+ // (20,12): error CS4007: Instance of type 'System.ReadOnlySpan>' cannot be preserved across 'await' or 'yield' boundary.
+ // => MemoryMarshal.CreateReadOnlySpan(
+ Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, @"MemoryMarshal.CreateReadOnlySpan(
+ ref Unsafe.As>, Buffer10>(
+ ref Unsafe.AsRef(in GetC(x).F)),
+ 10)").WithArguments("System.ReadOnlySpan>").WithLocation(20, 12)
);
}
@@ -4743,9 +4746,12 @@ static async Task FromResult(T r)
";
var comp = CreateCompilation(src + Buffer10Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe);
comp.VerifyEmitDiagnostics(
- // (24,13): error CS4007: 'await' cannot be used in an expression containing the type 'System.ReadOnlySpan'
- // [await FromResult(Get02(x))];
- Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "await FromResult(Get02(x))").WithArguments("System.ReadOnlySpan").WithLocation(24, 13)
+ // (20,12): error CS4007: Instance of type 'System.ReadOnlySpan' cannot be preserved across 'await' or 'yield' boundary.
+ // => MemoryMarshal.CreateReadOnlySpan(
+ Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, @"MemoryMarshal.CreateReadOnlySpan(
+ ref Unsafe.As, int>(
+ ref Unsafe.AsRef(in GetC(x).F[Get01()])),
+ 10)").WithArguments("System.ReadOnlySpan").WithLocation(20, 12)
);
}
@@ -20154,30 +20160,45 @@ .locals init (int V_0,
CompileAndVerify(comp, expectedOutput: " 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics();
}
- [Fact]
+ [ConditionalFact(typeof(CoreClrOnly))]
public void Foreach_InAsync_03()
{
var src = @"
class Program
{
- static async void Test()
+ static Buffer4 s_buffer;
+
+ static async System.Threading.Tasks.Task Main()
{
+ s_buffer[1] = 3;
+
foreach (ref int y in GetBuffer())
{
+ y *= y;
+ System.Console.Write(y);
}
await System.Threading.Tasks.Task.Yield();
+
+ System.Console.Write(s_buffer[1]);
}
- static ref Buffer4 GetBuffer() => throw null;
+ static ref Buffer4 GetBuffer() => ref s_buffer;
}
-";
- var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll);
- comp.VerifyDiagnostics(
- // (6,26): error CS8177: Async methods cannot have by-reference locals
+" + Buffer4Definition;
+
+ CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics(
+ // (10,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// foreach (ref int y in GetBuffer())
- Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "y").WithLocation(6, 26)
- );
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 26));
+
+ var expectedOutput = "09009";
+
+ CompileAndVerify(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe,
+ expectedOutput: expectedOutput).VerifyDiagnostics();
+
+ CompileAndVerify(src, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe,
+ expectedOutput: expectedOutput).VerifyDiagnostics();
}
[Fact]
@@ -20598,30 +20619,48 @@ .locals init (int V_0,
CompileAndVerify(comp, expectedOutput: " 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics();
}
- [Fact]
+ [ConditionalFact(typeof(CoreClrOnly))]
public void Foreach_InAsync_07()
{
var src = @"
class Program
{
- static async void Test()
+ static Buffer4 s_buffer;
+
+ static async System.Threading.Tasks.Task Main()
{
+ s_buffer[1] = 3;
+
+ int i = 0;
foreach (ref readonly int y in GetBuffer())
{
+ System.Console.Write(y);
+ s_buffer[i++]++;
+ System.Console.Write(y);
+ System.Console.Write(' ');
}
await System.Threading.Tasks.Task.Yield();
+
+ System.Console.Write(s_buffer[1]);
}
- static ref readonly Buffer4 GetBuffer() => throw null;
+ static ref readonly Buffer4 GetBuffer() => ref s_buffer;
}
-";
- var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll);
- comp.VerifyDiagnostics(
- // (6,35): error CS8177: Async methods cannot have by-reference locals
+" + Buffer4Definition;
+
+ CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics(
+ // (11,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// foreach (ref readonly int y in GetBuffer())
- Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "y").WithLocation(6, 35)
- );
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(11, 35));
+
+ var expectedOutput = "01 34 01 01 4";
+
+ CompileAndVerify(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe,
+ verify: Verification.FailsILVerify, expectedOutput: expectedOutput).VerifyDiagnostics();
+
+ CompileAndVerify(src, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe,
+ verify: Verification.FailsILVerify, expectedOutput: expectedOutput).VerifyDiagnostics();
}
[Fact]
@@ -20798,132 +20837,209 @@ .locals init (int V_0,
}
[ConditionalFact(typeof(CoreClrOnly))]
- public void Foreach_InIterator_01()
+ public void Foreach_InAsync_10()
{
var src = @"
class Program
{
- static private Buffer4 F = default;
- private static int index = 0;
+ static Buffer4 s_buffer;
- static void Main()
+ static async System.Threading.Tasks.Task Main()
{
- foreach (var a in Test())
- {}
+ s_buffer[1] = 3;
+
+ ref Buffer4 buffer = ref GetBuffer();
+ foreach (ref int y in buffer)
+ {
+ y *= y;
+ System.Console.Write(y);
+ }
+
+ await System.Threading.Tasks.Task.Yield();
+
+ System.Console.Write(s_buffer[1]);
}
- static System.Collections.Generic.IEnumerable Test()
+ static ref Buffer4 GetBuffer() => ref s_buffer;
+}
+" + Buffer4Definition;
+
+ CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics(
+ // (10,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // ref Buffer4 buffer = ref GetBuffer();
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "buffer").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 26),
+ // (11,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // foreach (ref int y in buffer)
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(11, 26));
+
+ var expectedOutput = "09009";
+
+ CompileAndVerify(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe,
+ expectedOutput: expectedOutput).VerifyDiagnostics();
+
+ CompileAndVerify(src, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe,
+ expectedOutput: expectedOutput).VerifyDiagnostics();
+ }
+
+ [Fact]
+ public void Foreach_InAsync_11()
+ {
+ var src = @"
+class Program
+{
+ static Buffer4 s_buffer;
+
+ static async System.Threading.Tasks.Task Main()
{
- yield return -1;
+ s_buffer[1] = 3;
- foreach (var y in GetBuffer())
+ foreach (ref int y in GetBuffer())
{
- Increment();
- System.Console.Write(' ');
+ await System.Threading.Tasks.Task.Yield();
+ y *= y;
System.Console.Write(y);
}
- yield return -2;
- }
+ await System.Threading.Tasks.Task.Yield();
- static ref Buffer4 GetBuffer()
- {
- System.Console.Write(-1);
- return ref F;
+ System.Console.Write(s_buffer[1]);
}
- static void Increment()
+ static ref Buffer4 GetBuffer() => ref s_buffer;
+}
+" + Buffer4Definition;
+
+ CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics(
+ // (10,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // foreach (ref int y in GetBuffer())
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 26));
+
+ var expectedDiagnostics = new[]
+ {
+ // (13,13): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+ // y *= y;
+ Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(13, 13),
+ // (13,18): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+ // y *= y;
+ Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(13, 18),
+ // (14,34): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+ // System.Console.Write(y);
+ Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(14, 34)
+ };
+
+ CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics);
+
+ CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics);
+ }
+
+ [Fact]
+ public void Foreach_InAsync_12()
+ {
+ var src = @"
+class Program
+{
+ static Buffer4 s_buffer;
+
+ static async System.Threading.Tasks.Task Main()
{
- index++;
+ s_buffer[1] = 3;
- if (index < 4)
+ foreach (ref int y in GetBuffer())
{
- F[index] = index;
+ y *= y;
+ System.Console.Write(y);
+ await System.Threading.Tasks.Task.Yield();
}
+
+ await System.Threading.Tasks.Task.Yield();
+
+ System.Console.Write(s_buffer[1]);
}
+
+ static ref Buffer4 GetBuffer() => ref s_buffer;
}
-";
- var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe);
- var verifier = CompileAndVerify(comp, expectedOutput: "-1 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics();
+" + Buffer4Definition;
- verifier.VerifyIL("Program.d__3.System.Collections.IEnumerator.MoveNext",
-@"
+ CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics(
+ // (10,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // foreach (ref int y in GetBuffer())
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 26));
+
+ var expectedDiagnostics = new[]
+ {
+ // (10,9): error CS8178: A reference returned by a call to 'Program.GetBuffer()' cannot be preserved across 'await' or 'yield' boundary.
+ // foreach (ref int y in GetBuffer())
+ Diagnostic(ErrorCode.ERR_RefReturningCallAndAwait, @"foreach (ref int y in GetBuffer())
+ {
+ y *= y;
+ System.Console.Write(y);
+ await System.Threading.Tasks.Task.Yield();
+ }").WithArguments("Program.GetBuffer()").WithLocation(10, 9)
+ };
+
+ CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics);
+
+ CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics);
+ }
+
+ [Fact]
+ public void Foreach_InAsync_13()
+ {
+ var src = @"
+class Program
{
- // Code size 126 (0x7e)
- .maxstack 2
- .locals init (int V_0,
- Buffer4& V_1,
- int V_2)
- IL_0000: ldarg.0
- IL_0001: ldfld ""int Program.d__3.<>1__state""
- IL_0006: stloc.0
- IL_0007: ldloc.0
- IL_0008: switch (
- IL_001b,
- IL_0032,
- IL_0075)
- IL_0019: ldc.i4.0
- IL_001a: ret
- IL_001b: ldarg.0
- IL_001c: ldc.i4.m1
- IL_001d: stfld ""int Program.d__3.<>1__state""
- IL_0022: ldarg.0
- IL_0023: ldc.i4.m1
- IL_0024: stfld ""int Program.d__3.<>2__current""
- IL_0029: ldarg.0
- IL_002a: ldc.i4.1
- IL_002b: stfld ""int Program.d__3.<>1__state""
- IL_0030: ldc.i4.1
- IL_0031: ret
- IL_0032: ldarg.0
- IL_0033: ldc.i4.m1
- IL_0034: stfld ""int Program.d__3.<>1__state""
- IL_0039: call ""ref Buffer4 Program.GetBuffer()""
- IL_003e: stloc.1
- IL_003f: ldc.i4.0
- IL_0040: stloc.2
- IL_0041: br.s IL_0060
- IL_0043: ldloc.1
- IL_0044: ldloc.2
- IL_0045: call ""ref int .InlineArrayElementRef, int>(ref Buffer4, int)""
- IL_004a: ldind.i4
- IL_004b: call ""void Program.Increment()""
- IL_0050: ldc.i4.s 32
- IL_0052: call ""void System.Console.Write(char)""
- IL_0057: call ""void System.Console.Write(int)""
- IL_005c: ldloc.2
- IL_005d: ldc.i4.1
- IL_005e: add
- IL_005f: stloc.2
- IL_0060: ldloc.2
- IL_0061: ldc.i4.4
- IL_0062: blt.s IL_0043
- IL_0064: ldarg.0
- IL_0065: ldc.i4.s -2
- IL_0067: stfld ""int Program.d__3.<>2__current""
- IL_006c: ldarg.0
- IL_006d: ldc.i4.2
- IL_006e: stfld ""int Program.d__3.<>1__state""
- IL_0073: ldc.i4.1
- IL_0074: ret
- IL_0075: ldarg.0
- IL_0076: ldc.i4.m1
- IL_0077: stfld ""int Program.d__3.<>1__state""
- IL_007c: ldc.i4.0
- IL_007d: ret
+ static Buffer4 s_buffer;
+
+ static async System.Threading.Tasks.Task Main()
+ {
+ s_buffer[1] = 3;
+
+ ref Buffer4 buffer = ref GetBuffer();
+ foreach (ref int y in buffer)
+ {
+ y *= y;
+ System.Console.Write(y);
+ await System.Threading.Tasks.Task.Yield();
+ }
+
+ await System.Threading.Tasks.Task.Yield();
+
+ System.Console.Write(s_buffer[1]);
+ }
+
+ static ref Buffer4 GetBuffer() => ref s_buffer;
}
-");
- comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.DebugExe);
- CompileAndVerify(comp, expectedOutput: "-1 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics();
+" + Buffer4Definition;
+
+ CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics(
+ // (10,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // ref Buffer4 buffer = ref GetBuffer();
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "buffer").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 26),
+ // (11,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // foreach (ref int y in buffer)
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(11, 26));
+
+ var expectedDiagnostics = new[]
+ {
+ // (11,31): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+ // foreach (ref int y in buffer)
+ Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "buffer").WithLocation(11, 31)
+ };
+
+ CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics);
+
+ CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics);
}
- [ConditionalFact(typeof(CoreClrOnly))]
- public void Foreach_InIterator_02()
+ [Fact]
+ public void Foreach_InAsync_14()
{
var src = @"
+using System.Threading.Tasks;
+
class C
{
- public Buffer4 F = default;
+ public readonly Buffer4 F = default;
}
class Program
@@ -20933,19 +21049,20 @@ class Program
static void Main()
{
- foreach (var a in Test(c))
- {}
+ Test(c).Wait();
}
- static System.Collections.Generic.IEnumerable Test(C x)
+ static async Task Test(C x)
{
- foreach (var y in x.F)
+ ref readonly Buffer4 f = ref x.F;
+ foreach (var y in f)
{
Increment();
System.Console.Write(' ');
System.Console.Write(y);
- yield return -1;
+ await Task.Yield();
+ await Task.Delay(2);
}
}
@@ -20955,146 +21072,266 @@ static void Increment()
if (index < 4)
{
- c.F[index] = index;
+ System.Runtime.CompilerServices.Unsafe.AsRef(in c.F)[index] = index;
}
}
}
-";
- var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe);
- var verifier = CompileAndVerify(comp, expectedOutput: " 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics();
+" + Buffer4Definition;
- verifier.VerifyIL("Program.d__3.System.Collections.IEnumerator.MoveNext",
-@"
+ CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics(
+ // (21,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // ref readonly Buffer4 f = ref x.F;
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "f").WithArguments("ref and unsafe in async and iterator methods").WithLocation(21, 35));
+
+ var expectedDiagnostics = new[]
+ {
+ // (22,27): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+ // foreach (var y in f)
+ Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "f").WithLocation(22, 27)
+ };
+
+ CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics);
+
+ CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics);
+ }
+
+ [Fact]
+ public void Foreach_InAsync_15()
+ {
+ var src = @"
+class Program
{
- // Code size 151 (0x97)
- .maxstack 3
- .locals init (int V_0)
- IL_0000: ldarg.0
- IL_0001: ldfld ""int Program.d__3.<>1__state""
- IL_0006: stloc.0
- IL_0007: ldloc.0
- IL_0008: brfalse.s IL_0010
- IL_000a: ldloc.0
- IL_000b: ldc.i4.1
- IL_000c: beq.s IL_0070
- IL_000e: ldc.i4.0
- IL_000f: ret
- IL_0010: ldarg.0
- IL_0011: ldc.i4.m1
- IL_0012: stfld ""int Program.d__3.<>1__state""
- IL_0017: ldarg.0
- IL_0018: ldarg.0
- IL_0019: ldfld ""C Program.d__3.x""
- IL_001e: stfld ""C Program.d__3.<>7__wrap2""
- IL_0023: ldarg.0
- IL_0024: ldfld ""C Program.d__3.<>7__wrap2""
- IL_0029: ldfld ""Buffer4 C.F""
- IL_002e: pop
- IL_002f: ldarg.0
- IL_0030: ldc.i4.0
- IL_0031: stfld ""int Program.d__3.<>7__wrap1""
- IL_0036: br.s IL_0085
- IL_0038: ldarg.0
- IL_0039: ldfld ""C Program.d__3.<>7__wrap2""
- IL_003e: ldflda ""Buffer4 C.F""
- IL_0043: ldarg.0
- IL_0044: ldfld ""int Program.d__3.<>7__wrap1""
- IL_0049: call ""ref int .InlineArrayElementRef, int>(ref Buffer4, int)""
- IL_004e: ldind.i4
- IL_004f: call ""void Program.Increment()""
- IL_0054: ldc.i4.s 32
- IL_0056: call ""void System.Console.Write(char)""
- IL_005b: call ""void System.Console.Write(int)""
- IL_0060: ldarg.0
- IL_0061: ldc.i4.m1
- IL_0062: stfld ""int Program.d__3.<>2__current""
- IL_0067: ldarg.0
- IL_0068: ldc.i4.1
- IL_0069: stfld ""int Program.d__3.<>1__state""
- IL_006e: ldc.i4.1
- IL_006f: ret
- IL_0070: ldarg.0
- IL_0071: ldc.i4.m1
- IL_0072: stfld ""int Program.d__3.<>1__state""
- IL_0077: ldarg.0
- IL_0078: ldarg.0
- IL_0079: ldfld ""int Program.d__3.<>7__wrap1""
- IL_007e: ldc.i4.1
- IL_007f: add
- IL_0080: stfld ""int Program.d__3.<>7__wrap1""
- IL_0085: ldarg.0
- IL_0086: ldfld ""int Program.d__3.<>7__wrap1""
- IL_008b: ldc.i4.4
- IL_008c: blt.s IL_0038
- IL_008e: ldarg.0
- IL_008f: ldnull
- IL_0090: stfld ""C Program.d__3.<>7__wrap2""
- IL_0095: ldc.i4.0
- IL_0096: ret
+ static Buffer4 s_buffer;
+
+ static async System.Threading.Tasks.Task Main()
+ {
+ foreach (ref readonly int y in GetBuffer())
+ {
+ System.Console.Write(y);
+ await System.Threading.Tasks.Task.Yield();
+ }
+
+ await System.Threading.Tasks.Task.Yield();
+ }
+
+ static ref readonly Buffer4 GetBuffer() => ref s_buffer;
}
-");
- comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.DebugExe);
- CompileAndVerify(comp, expectedOutput: " 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics();
+" + Buffer4Definition;
+
+ CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics(
+ // (8,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // foreach (ref readonly int y in GetBuffer())
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 35));
+
+ var expectedDiagnostics = new[]
+ {
+ // (8,9): error CS8178: A reference returned by a call to 'Program.GetBuffer()' cannot be preserved across 'await' or 'yield' boundary.
+ // foreach (ref readonly int y in GetBuffer())
+ Diagnostic(ErrorCode.ERR_RefReturningCallAndAwait, @"foreach (ref readonly int y in GetBuffer())
+ {
+ System.Console.Write(y);
+ await System.Threading.Tasks.Task.Yield();
+ }").WithArguments("Program.GetBuffer()").WithLocation(8, 9)
+ };
+
+ CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics);
+
+ CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics);
}
[Fact]
- public void Foreach_InIterator_03()
+ public void Foreach_InAsync_16()
{
var src = @"
class Program
{
- static System.Collections.Generic.IEnumerable Test()
+ static Buffer4 s_buffer;
+
+ static async System.Threading.Tasks.Task Main()
{
- foreach (ref int y in GetBuffer())
+ foreach (ref readonly int y in GetBuffer())
{
+ await System.Threading.Tasks.Task.Yield();
+ System.Console.Write(y);
}
- yield return -1;
+ await System.Threading.Tasks.Task.Yield();
}
- static ref Buffer4 GetBuffer() => throw null;
+ static ref readonly Buffer4 GetBuffer() => ref s_buffer;
}
-";
- var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll);
- comp.VerifyDiagnostics(
- // (6,26): error CS8176: Iterators cannot have by-reference locals
- // foreach (ref int y in GetBuffer())
- Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "y").WithLocation(6, 26)
- );
+" + Buffer4Definition;
+
+ CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics(
+ // (8,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // foreach (ref readonly int y in GetBuffer())
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 35));
+
+ var expectedDiagnostics = new[]
+ {
+ // (11,34): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+ // System.Console.Write(y);
+ Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(11, 34)
+ };
+
+ CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics);
+
+ CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics);
+ }
+
+ [ConditionalFact(typeof(CoreClrOnly))]
+ public void Foreach_InAsync_17()
+ {
+ var src = @"
+using System.Threading.Tasks;
+
+class C
+{
+ public readonly Buffer4 F = default;
+}
+
+class Program
+{
+ private static C c = new C();
+ private static int index = 0;
+
+ static void Main()
+ {
+ Test(c).Wait();
+ }
+
+ static async Task Test(C x)
+ {
+ foreach (ref readonly int y in x.F)
+ {
+ Increment();
+ System.Console.Write(' ');
+ System.Console.Write(y);
+
+ await Task.Yield();
+ await Task.Delay(2);
+ }
+ }
+
+ static void Increment()
+ {
+ index++;
+
+ if (index < 4)
+ {
+ System.Runtime.CompilerServices.Unsafe.AsRef(in c.F)[index] = index;
+ }
+ }
+}
+" + Buffer4Definition;
+ var expectedOutput = " 0 1 2 3";
+ var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe);
+ var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.Fails).VerifyDiagnostics();
+ comp = CreateCompilation(src, targetFramework: TargetFramework.Net80, options: TestOptions.DebugExe);
+ CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.Fails).VerifyDiagnostics();
}
[Fact]
- public void Foreach_InIterator_04()
+ public void Foreach_InAsync_18()
{
var src = @"
+using System.Threading.Tasks;
+
+class C
+{
+ public readonly Buffer4 F = default;
+}
+
class Program
{
- static System.Collections.Generic.IEnumerable Test()
+ static async Task Test(C x)
{
- foreach (int y in GetBuffer())
+ foreach (ref readonly int y in x.F)
{
- yield return -1;
+ await Task.Yield();
+ System.Console.Write(y);
}
}
+}
+" + Buffer4Definition;
- static ref Buffer4 GetBuffer() => throw null;
+ CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12).VerifyDiagnostics(
+ // (13,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // foreach (ref readonly int y in x.F)
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(13, 35));
+
+ var expectedDiagnostics = new[]
+ {
+ // (16,34): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+ // System.Console.Write(y);
+ Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(16, 34)
+ };
+
+ CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedDiagnostics);
+ CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics);
+ }
+
+ [Fact]
+ public void Foreach_InAsync_19()
+ {
+ var src = @"
+using System.Threading.Tasks;
+
+class C
+{
+ public readonly Buffer4 F = default;
}
-";
- var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll);
- comp.VerifyEmitDiagnostics(
- // (6,9): error CS8178: A reference returned by a call to 'Program.GetBuffer()' cannot be preserved across 'await' or 'yield' boundary.
- // foreach (int y in GetBuffer())
- Diagnostic(ErrorCode.ERR_RefReturningCallAndAwait,
- @"foreach (int y in GetBuffer())
+class Program
+{
+ static async Task Test(C x)
+ {
+ ref readonly Buffer4 f = ref x.F;
+
+ foreach (var i in f) System.Console.Write(i);
+
+ foreach (var y in f)
{
- yield return -1;
- }").WithArguments("Program.GetBuffer()").WithLocation(6, 9)
- );
+ System.Console.Write(y);
+ await Task.Yield();
+ }
+
+ foreach (var j in f) System.Console.Write(j);
+
+ foreach (var z in f)
+ {
+ System.Console.Write(z);
+ await Task.Yield();
+ }
+ }
+}
+" + Buffer4Definition;
+
+ CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics(
+ // (13,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // ref readonly Buffer4 f = ref x.F;
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "f").WithArguments("ref and unsafe in async and iterator methods").WithLocation(13, 35));
+
+ var expectedDiagnostics = new[]
+ {
+ // (17,27): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+ // foreach (var y in f)
+ Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "f").WithLocation(17, 27),
+ // (23,27): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+ // foreach (var j in f) System.Console.Write(j);
+ Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "f").WithLocation(23, 27),
+ // (25,27): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary.
+ // foreach (var z in f)
+ Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "f").WithLocation(25, 27)
+ };
+
+ CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics);
+
+ CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics);
}
[ConditionalFact(typeof(CoreClrOnly))]
- public void Foreach_InIterator_05()
+ public void Foreach_InIterator_01()
{
var src = @"
class Program
@@ -21122,7 +21359,7 @@ static System.Collections.Generic.IEnumerable Test()
yield return -2;
}
- static ref readonly Buffer4 GetBuffer()
+ static ref Buffer4 GetBuffer()
{
System.Console.Write(-1);
return ref F;
@@ -21174,14 +21411,14 @@ .locals init (int V_0,
IL_0032: ldarg.0
IL_0033: ldc.i4.m1
IL_0034: stfld ""int Program.d__3.<>1__state""
- IL_0039: call ""ref readonly Buffer4 Program.GetBuffer()""
+ IL_0039: call ""ref Buffer4 Program.GetBuffer()""
IL_003e: stloc.1
IL_003f: ldc.i4.0
IL_0040: stloc.2
IL_0041: br.s IL_0060
IL_0043: ldloc.1
IL_0044: ldloc.2
- IL_0045: call ""ref readonly int .InlineArrayElementRefReadOnly, int>(in Buffer4, int)""
+ IL_0045: call ""ref int .InlineArrayElementRef, int>(ref Buffer4, int)""
IL_004a: ldind.i4
IL_004b: call ""void Program.Increment()""
IL_0050: ldc.i4.s 32
@@ -21214,12 +21451,12 @@ .locals init (int V_0,
}
[ConditionalFact(typeof(CoreClrOnly))]
- public void Foreach_InIterator_06()
+ public void Foreach_InIterator_02()
{
var src = @"
class C
{
- public readonly Buffer4 F = default;
+ public Buffer4 F = default;
}
class Program
@@ -21251,7 +21488,7 @@ static void Increment()
if (index < 4)
{
- System.Runtime.CompilerServices.Unsafe.AsRef(in c.F)[index] = index;
+ c.F[index] = index;
}
}
}
@@ -21295,7 +21532,7 @@ .locals init (int V_0)
IL_003e: ldflda ""Buffer4 C.F""
IL_0043: ldarg.0
IL_0044: ldfld ""int Program.d__3.<>7__wrap1""
- IL_0049: call ""ref readonly int .InlineArrayElementRefReadOnly, int>(in Buffer4, int)""
+ IL_0049: call ""ref int .InlineArrayElementRef, int>(ref Buffer4, int)""
IL_004e: ldind.i4
IL_004f: call ""void Program.Increment()""
IL_0054: ldc.i4.s 32
@@ -21333,34 +21570,57 @@ .locals init (int V_0)
CompileAndVerify(comp, expectedOutput: " 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics();
}
- [Fact]
- public void Foreach_InIterator_07()
+ [ConditionalFact(typeof(CoreClrOnly))]
+ public void Foreach_InIterator_03()
{
var src = @"
class Program
{
+ static Buffer4 s_buffer;
+
+ static void Main()
+ {
+ s_buffer[2] = 3;
+
+ foreach (int x in Test())
+ {
+ System.Console.Write(x);
+ }
+ }
+
static System.Collections.Generic.IEnumerable Test()
{
- foreach (ref readonly int y in GetBuffer())
+ foreach (ref int y in GetBuffer())
{
+ y *= y;
+ System.Console.Write(y);
}
yield return -1;
+
+ System.Console.Write(s_buffer[2]);
}
- static ref readonly Buffer4 GetBuffer() => throw null;
+ static ref Buffer4 GetBuffer() => ref s_buffer;
}
-";
- var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll);
- comp.VerifyDiagnostics(
- // (6,35): error CS8176: Iterators cannot have by-reference locals
- // foreach (ref readonly int y in GetBuffer())
- Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "y").WithLocation(6, 35)
- );
+" + Buffer4Definition;
+
+ CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics(
+ // (18,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
+ // foreach (ref int y in GetBuffer())
+ Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(18, 26));
+
+ var expectedOutput = "0090-19";
+
+ CompileAndVerify(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe,
+ expectedOutput: expectedOutput).VerifyDiagnostics();
+
+ CompileAndVerify(src, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe,
+ expectedOutput: expectedOutput).VerifyDiagnostics();
}
[Fact]
- public void Foreach_InIterator_08()
+ public void Foreach_InIterator_04()
{
var src = @"
class Program
@@ -21373,7 +21633,7 @@ static System.Collections.Generic.IEnumerable Test()
}
}
- static ref readonly Buffer4 GetBuffer() => throw null;
+ static ref Buffer4 GetBuffer() => throw null;
}
";
var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll);
@@ -21390,11 +21650,14 @@ static System.Collections.Generic.IEnumerable Test()
}
[ConditionalFact(typeof(CoreClrOnly))]
- public void Foreach_InIterator_09()
+ public void Foreach_InIterator_05()
{
var src = @"
class Program
{
+ static private Buffer4 F = default;
+ private static int index = 0;
+
static void Main()
{
foreach (var a in Test())
@@ -21403,92 +21666,929 @@ static void Main()
static System.Collections.Generic.IEnumerable Test()
{
+ yield return -1;
+
foreach (var y in GetBuffer())
{
+ Increment();
System.Console.Write(' ');
System.Console.Write(y);
- yield return -1;
}
+
+ yield return -2;
}
- static Buffer4 GetBuffer()
+ static ref readonly Buffer4 GetBuffer()
{
- Buffer4 x = default;
- x[0] = 111;
- x[1] = 112;
- x[2] = 113;
- x[3] = 114;
-
System.Console.Write(-1);
- return x;
+ return ref F;
+ }
+
+ static void Increment()
+ {
+ index++;
+
+ if (index < 4)
+ {
+ F[index] = index;
+ }
}
}
";
var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe);
- var verifier = CompileAndVerify(comp, expectedOutput: "-1 111 112 113 114").VerifyDiagnostics();
+ var verifier = CompileAndVerify(comp, expectedOutput: "-1 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics();
- verifier.VerifyIL("Program.d__1.System.Collections.IEnumerator.MoveNext",
+ verifier.VerifyIL("Program.d__3.System.Collections.IEnumerator.MoveNext",
@"
{
- // Code size 121 (0x79)
+ // Code size 126 (0x7e)
+ .maxstack 2
+ .locals init (int V_0,
+ Buffer4& V_1,
+ int V_2)
+ IL_0000: ldarg.0
+ IL_0001: ldfld ""int Program.d__3.<>1__state""
+ IL_0006: stloc.0
+ IL_0007: ldloc.0
+ IL_0008: switch (
+ IL_001b,
+ IL_0032,
+ IL_0075)
+ IL_0019: ldc.i4.0
+ IL_001a: ret
+ IL_001b: ldarg.0
+ IL_001c: ldc.i4.m1
+ IL_001d: stfld ""int Program.d__3.<>1__state""
+ IL_0022: ldarg.0
+ IL_0023: ldc.i4.m1
+ IL_0024: stfld ""int Program.d__3.<>2__current""
+ IL_0029: ldarg.0
+ IL_002a: ldc.i4.1
+ IL_002b: stfld ""int Program.d__3.<>1__state""
+ IL_0030: ldc.i4.1
+ IL_0031: ret
+ IL_0032: ldarg.0
+ IL_0033: ldc.i4.m1
+ IL_0034: stfld ""int Program.d__3.<>1__state""
+ IL_0039: call ""ref readonly Buffer4 Program.GetBuffer()""
+ IL_003e: stloc.1
+ IL_003f: ldc.i4.0
+ IL_0040: stloc.2
+ IL_0041: br.s IL_0060
+ IL_0043: ldloc.1
+ IL_0044: ldloc.2
+ IL_0045: call ""ref readonly int .InlineArrayElementRefReadOnly, int>(in Buffer4, int)""
+ IL_004a: ldind.i4
+ IL_004b: call ""void Program.Increment()""
+ IL_0050: ldc.i4.s 32
+ IL_0052: call ""void System.Console.Write(char)""
+ IL_0057: call ""void System.Console.Write(int)""
+ IL_005c: ldloc.2
+ IL_005d: ldc.i4.1
+ IL_005e: add
+ IL_005f: stloc.2
+ IL_0060: ldloc.2
+ IL_0061: ldc.i4.4
+ IL_0062: blt.s IL_0043
+ IL_0064: ldarg.0
+ IL_0065: ldc.i4.s -2
+ IL_0067: stfld ""int Program.d__3.<>2__current""
+ IL_006c: ldarg.0
+ IL_006d: ldc.i4.2
+ IL_006e: stfld ""int Program.d__3.<>1__state""
+ IL_0073: ldc.i4.1
+ IL_0074: ret
+ IL_0075: ldarg.0
+ IL_0076: ldc.i4.m1
+ IL_0077: stfld ""int Program.d__3.<>1__state""
+ IL_007c: ldc.i4.0
+ IL_007d: ret
+}
+");
+ comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.DebugExe);
+ CompileAndVerify(comp, expectedOutput: "-1 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics();
+ }
+
+ [ConditionalFact(typeof(CoreClrOnly))]
+ public void Foreach_InIterator_06()
+ {
+ var src = @"
+class C
+{
+ public readonly Buffer4 F = default;
+}
+
+class Program
+{
+ private static C c = new C();
+ private static int index = 0;
+
+ static void Main()
+ {
+ foreach (var a in Test(c))
+ {}
+ }
+
+ static System.Collections.Generic.IEnumerable Test(C x)
+ {
+ foreach (var y in x.F)
+ {
+ Increment();
+ System.Console.Write(' ');
+ System.Console.Write(y);
+
+ yield return -1;
+ }
+ }
+
+ static void Increment()
+ {
+ index++;
+
+ if (index < 4)
+ {
+ System.Runtime.CompilerServices.Unsafe.AsRef(in c.F)[index] = index;
+ }
+ }
+}
+";
+ var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe);
+ var verifier = CompileAndVerify(comp, expectedOutput: " 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics();
+
+ verifier.VerifyIL("Program.d__3.System.Collections.IEnumerator.MoveNext",
+@"
+{
+ // Code size 151 (0x97)
.maxstack 3
.locals init (int V_0)
IL_0000: ldarg.0
- IL_0001: ldfld ""int Program.d__1.<>1__state""
+ IL_0001: ldfld ""int Program.d__3.<>1__state""
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: brfalse.s IL_0010
IL_000a: ldloc.0
IL_000b: ldc.i4.1
- IL_000c: beq.s IL_0059
+ IL_000c: beq.s IL_0070
IL_000e: ldc.i4.0
IL_000f: ret
IL_0010: ldarg.0
IL_0011: ldc.i4.m1
- IL_0012: stfld ""int Program.d__1.<>1__state""
+ IL_0012: stfld ""int Program.d__3.<>1__state""
IL_0017: ldarg.0
- IL_0018: call ""Buffer4 Program.GetBuffer()""
- IL_001d: stfld ""Buffer4 Program.d__1.<>7__wrap1""
- IL_0022: ldarg.0
- IL_0023: ldc.i4.0
- IL_0024: stfld ""int Program.d__1.<>7__wrap2""
- IL_0029: br.s IL_006e
- IL_002b: ldarg.0
- IL_002c: ldflda ""Buffer4 Program.d__1.<>7__wrap1""
- IL_0031: ldarg.0
- IL_0032: ldfld ""int Program.d__1.<>7__wrap2""
- IL_0037: call ""ref readonly int .InlineArrayElementRefReadOnly, int>(in Buffer4, int)""
- IL_003c: ldind.i4
- IL_003d: ldc.i4.s 32
- IL_003f: call ""void System.Console.Write(char)""
- IL_0044: call ""void System.Console.Write(int)""
- IL_0049: ldarg.0
- IL_004a: ldc.i4.m1
- IL_004b: stfld ""int Program.d__1.<>2__current""
- IL_0050: ldarg.0
- IL_0051: ldc.i4.1
- IL_0052: stfld ""int Program.d__1.<>1__state""
- IL_0057: ldc.i4.1
- IL_0058: ret
- IL_0059: ldarg.0
- IL_005a: ldc.i4.m1
- IL_005b: stfld ""int Program.d__1.<>1__state""
+ IL_0018: ldarg.0
+ IL_0019: ldfld ""C Program.d__3.x""
+ IL_001e: stfld ""C Program.d__3.<>7__wrap2""
+ IL_0023: ldarg.0
+ IL_0024: ldfld ""C Program.d__3.<>7__wrap2""
+ IL_0029: ldfld ""Buffer4 C.F""
+ IL_002e: pop
+ IL_002f: ldarg.0
+ IL_0030: ldc.i4.0
+ IL_0031: stfld ""int Program.d__3.<>7__wrap1""
+ IL_0036: br.s IL_0085
+ IL_0038: ldarg.0
+ IL_0039: ldfld ""C Program.d__3.<>7__wrap2""
+ IL_003e: ldflda ""Buffer4 C.F""
+ IL_0043: ldarg.0
+ IL_0044: ldfld ""int Program.d__3.<>7__wrap1""
+ IL_0049: call ""ref readonly int .InlineArrayElementRefReadOnly, int>(in Buffer4, int)""
+ IL_004e: ldind.i4
+ IL_004f: call ""void Program.Increment()""
+ IL_0054: ldc.i4.s 32
+ IL_0056: call ""void System.Console.Write(char)""
+ IL_005b: call ""void System.Console.Write(int)""
IL_0060: ldarg.0
- IL_0061: ldarg.0
- IL_0062: ldfld ""int Program.d__1.<>7__wrap2""
- IL_0067: ldc.i4.1
- IL_0068: add
- IL_0069: stfld ""int Program.d__1.<>7__wrap2""
- IL_006e: ldarg.0
- IL_006f: ldfld ""int Program.d__1.<>7__wrap2""
- IL_0074: ldc.i4.4
- IL_0075: blt.s IL_002b
- IL_0077: ldc.i4.0
- IL_0078: ret
+ IL_0061: ldc.i4.m1
+ IL_0062: stfld ""int Program.