diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index be221bed765f8..474fcd46b608b 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -6996,6 +6996,12 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
The 'scoped' modifier of parameter '{0}' doesn't match partial definition.
+
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+
+
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+
A fixed field must not be a ref field.
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
index 5153ca9d395e1..b5c4b2797ac51 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@@ -2448,6 +2448,9 @@ internal enum ErrorCode
ERR_ExtensionParameterInStaticContext = 9347,
ERR_CompilationUnitUnexpected = 9348,
+ ERR_ScopedAfterInOutRefReadonly = 9349,
+ ERR_InvalidModifierAfterScoped = 9350,
+
// Note: you will need to do the following after adding errors:
// 1) Update ErrorFacts.IsBuildOnlyDiagnostic (src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs)
// 2) Add message to CSharpResources.resx
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
index a99746c3a5f12..4f95bb82a4bd3 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
@@ -2555,6 +2555,8 @@ or ErrorCode.ERR_EqualityOperatorInPatternNotSupported
or ErrorCode.ERR_InequalityOperatorInPatternNotSupported
or ErrorCode.ERR_DesignatorBeforePropertyPattern
or ErrorCode.ERR_CompilationUnitUnexpected
+ or ErrorCode.ERR_ScopedAfterInOutRefReadonly
+ or ErrorCode.ERR_InvalidModifierAfterScoped
=> false,
};
#pragma warning restore CS8524 // The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value.
diff --git a/src/Compilers/CSharp/Portable/Errors/MessageID.cs b/src/Compilers/CSharp/Portable/Errors/MessageID.cs
index 5933baf7c5b04..463f90286d2d8 100644
--- a/src/Compilers/CSharp/Portable/Errors/MessageID.cs
+++ b/src/Compilers/CSharp/Portable/Errors/MessageID.cs
@@ -487,7 +487,7 @@ internal static LanguageVersion RequiredVersion(this MessageID feature)
// C# preview features.
//return LanguageVersion.Preview;
- // C# 13.0 features.
+ // C# 14.0 features.
case MessageID.IDS_FeatureFieldKeyword:
case MessageID.IDS_FeatureFirstClassSpan:
case MessageID.IDS_FeatureUnboundGenericTypesInNameof:
diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
index 7d9e2b418d691..f34e2393b13d4 100644
--- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
+++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
@@ -4834,7 +4834,9 @@ private bool IsPossibleParameter()
return this.IsTrueIdentifier();
default:
- return IsParameterModifierExcludingScoped(this.CurrentToken) || IsPossibleScopedKeyword(isFunctionPointerParameter: false) || IsPredefinedType(this.CurrentToken.Kind);
+ return IsParameterModifierExcludingScoped(this.CurrentToken) ||
+ IsDefiniteScopedModifier(isFunctionPointerParameter: false, isLambdaParameter: false) ||
+ IsPredefinedType(this.CurrentToken.Kind);
}
}
@@ -4961,32 +4963,50 @@ private static bool IsParameterModifierExcludingScoped(SyntaxToken token)
private void ParseParameterModifiers(SyntaxListBuilder modifiers, bool isFunctionPointerParameter, bool isLambdaParameter)
{
- bool tryScoped = true;
+ Debug.Assert(!(isFunctionPointerParameter && isLambdaParameter), "Can't be parsing parameters for both a function pointer and a lambda at the same time");
- while (IsParameterModifierExcludingScoped(this.CurrentToken))
+ var seenScoped = false;
+ while (true)
{
- if (this.CurrentToken.Kind is SyntaxKind.RefKeyword or SyntaxKind.OutKeyword or SyntaxKind.InKeyword or SyntaxKind.ReadOnlyKeyword)
+ // Normal keyword-modifier (in/out/ref/readonly/params/this). Always safe to consume.
+ if (IsParameterModifierExcludingScoped(this.CurrentToken))
{
- tryScoped = false;
+ modifiers.Add(this.EatToken());
+ continue;
}
- modifiers.Add(this.EatToken());
- }
-
- if (tryScoped)
- {
- SyntaxToken scopedKeyword = ParsePossibleScopedKeyword(isFunctionPointerParameter, isLambdaParameter);
-
- if (scopedKeyword != null)
+ // 'scoped' modifier. May be ambiguous with a type/identifier. And has changed parsing rules between
+ // C#13/14 inside a lambda parameter list.
+ if (this.IsDefiniteScopedModifier(isFunctionPointerParameter, isLambdaParameter))
{
- modifiers.Add(scopedKeyword);
-
- // Look if ref/out/in/readonly are next
- while (this.CurrentToken.Kind is SyntaxKind.RefKeyword or SyntaxKind.OutKeyword or SyntaxKind.InKeyword or SyntaxKind.ReadOnlyKeyword)
+ // First scoped-modifier is always considered the modifier.
+ if (!seenScoped)
{
- modifiers.Add(this.EatToken());
+ seenScoped = true;
+ modifiers.Add(this.EatContextualToken(SyntaxKind.ScopedKeyword));
+ continue;
+ }
+ else
+ {
+ // If we've already seen `scoped` then we may have a situation like `scoped scoped`. This could
+ // be duplicated modifier, or it could be that the second `scoped` is actually the identifier of
+ // a parameter.
+ //
+ // Places where it is an identifier are:
+ //
+ // `(scoped scoped) =>`
+ // `(scoped scoped, ...) =>`
+ // `(scoped scoped = ...) =>`
+ if (this.PeekToken(1).Kind is not (SyntaxKind.CloseParenToken or SyntaxKind.CommaToken or SyntaxKind.EqualsToken))
+ {
+ modifiers.Add(this.EatContextualToken(SyntaxKind.ScopedKeyword));
+ continue;
+ }
}
}
+
+ // Not a modifier. We're done.
+ return;
}
}
@@ -8464,7 +8484,7 @@ private bool IsPossibleLocalDeclarationStatement(bool isGlobalScriptLevel)
return true;
}
- if (IsPossibleScopedKeyword(isFunctionPointerParameter: false))
+ if (IsDefiniteScopedModifier(isFunctionPointerParameter: false, isLambdaParameter: false))
{
return true;
}
@@ -8482,12 +8502,6 @@ private bool IsPossibleLocalDeclarationStatement(bool isGlobalScriptLevel)
return IsPossibleFirstTypedIdentifierInLocalDeclarationStatement(isGlobalScriptLevel);
}
- private bool IsPossibleScopedKeyword(bool isFunctionPointerParameter)
- {
- using var _ = this.GetDisposableResetPoint(resetOnDispose: true);
- return ParsePossibleScopedKeyword(isFunctionPointerParameter, isLambdaParameter: false) != null;
- }
-
private bool IsPossibleFirstTypedIdentifierInLocalDeclarationStatement(bool isGlobalScriptLevel)
{
bool? typedIdentifier = IsPossibleTypedIdentifierStart(this.CurrentToken, this.PeekToken(1), allowThisKeyword: false);
@@ -8623,7 +8637,7 @@ private bool IsPossibleTopLevelUsingLocalDeclarationStatement()
// Skip 'using' keyword
EatToken();
- if (IsPossibleScopedKeyword(isFunctionPointerParameter: false))
+ if (IsDefiniteScopedModifier(isFunctionPointerParameter: false, isLambdaParameter: false))
{
return true;
}
@@ -10518,41 +10532,34 @@ private StatementSyntax ParseLocalDeclarationStatement(SyntaxList{0} není platný název parametru z {1}.
+
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+
+
The modifier '{0}' is not valid for this item in C# {1}. Please use language version '{2}' or greater.
Modifikátor {0} není platný pro tuto položku v jazyce C# {1}. Použijte prosím verzi jazyka {2} nebo vyšší.
@@ -2357,6 +2362,11 @@
Cílový modul runtime nepodporuje rozšiřitelné konvence volání ani konvence volání výchozí pro prostředí modulu runtime.
+
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+
+
The 'scoped' modifier cannot be used with discard.
Modifikátor scoped nejde použít s proměnnou typu discard.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
index cc832bbc9e59a..0f45cb89e4f4e 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
@@ -1457,6 +1457,11 @@
"{0}" ist kein gültiger Parametername von "{1}".
+
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+
+
The modifier '{0}' is not valid for this item in C# {1}. Please use language version '{2}' or greater.
Der Modifizierer "{0}" ist für dieses Element in C# {1} ungültig. Verwenden Sie Sprachversion {2} oder höher.
@@ -2357,6 +2362,11 @@
Die Zielruntime unterstützt keine erweiterbaren Aufrufkonventionen oder Standardaufrufkonventionen der Runtime-Umgebung.
+
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+
+
The 'scoped' modifier cannot be used with discard.
Der Modifizierer „scoped“ kann nicht mit „discard“ verwendet werden.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
index 63c1713972390..adb65da6e83cb 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
@@ -1457,6 +1457,11 @@
"{0}" no es un nombre de parámetro válido para "{1}".
+
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+
+
The modifier '{0}' is not valid for this item in C# {1}. Please use language version '{2}' or greater.
El modificador "{0}" no es válido para este elemento en C# {1}. Use la versión de lenguaje "{2}" o una posterior.
@@ -2357,6 +2362,11 @@
El entorno de ejecución de destino no admite convenciones de llamada predeterminadas de entorno en tiempo de ejecución o extensible.
+
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+
+
The 'scoped' modifier cannot be used with discard.
El modificador “scoped” no se puede usar con discard.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
index 2514cadd8555e..1c4a282cd3f72 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
@@ -1457,6 +1457,11 @@
« {0} » n’est pas un nom de paramètre valide de « {1} ».
+
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+
+
The modifier '{0}' is not valid for this item in C# {1}. Please use language version '{2}' or greater.
Le modificateur '{0}' est non valide pour cet élément en C# {1}. Utilisez la version de langage '{2}' ou une version ultérieure.
@@ -2357,6 +2362,11 @@
Le runtime cible ne prend pas en charge les conventions d'appel par défaut des environnements extensibles ou d'exécution.
+
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+
+
The 'scoped' modifier cannot be used with discard.
Le modificateur « Scoped » ne peut pas être utilisé avec discard.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
index 8e9ff5da71416..0ac3d14141c60 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
@@ -1457,6 +1457,11 @@
'{0}' non è un nome di parametro valido da '{1}'.
+
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+
+
The modifier '{0}' is not valid for this item in C# {1}. Please use language version '{2}' or greater.
Il modificatore '{0}' non è valido per questo elemento in C# {1}. Usare la versione '{2}' o versioni successive del linguaggio.
@@ -2357,6 +2362,11 @@
Il runtime di destinazione non supporta convenzioni di chiamata predefinite estendibili o dell'ambiente di runtime.
+
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+
+
The 'scoped' modifier cannot be used with discard.
Non è possibile usare il modificatore 'scoped' con discard.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
index f85cba504ee36..f2d549781dd8b 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
@@ -1457,6 +1457,11 @@
'{0}' は、'{1}' からの有効なパラメーター名ではありません。
+
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+
+
The modifier '{0}' is not valid for this item in C# {1}. Please use language version '{2}' or greater.
C# {1} では、修飾子 '{0}' はこの項目に対して有効ではありません。'{2}' 以上の言語バージョンをご使用ください。
@@ -2357,6 +2362,11 @@
ターゲット ランタイムは、拡張可能またはランタイム環境の既定の呼び出し規則をサポートしていません。
+
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+
+
The 'scoped' modifier cannot be used with discard.
'scoped' 修飾子を discard と共に使用することはできません。
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
index 8284244bdb176..393077dfb3858 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
@@ -1457,6 +1457,11 @@
'{0}'은(는) '{1}'의 유효한 매개 변수 이름이 아닙니다.
+
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+
+
The modifier '{0}' is not valid for this item in C# {1}. Please use language version '{2}' or greater.
C# {1}의 이 항목에는 '{0}' 한정자가 유효하지 않습니다. 언어 버전 '{2}' 이상을 사용하세요.
@@ -2357,6 +2362,11 @@
대상 런타임에서 확장 가능 또는 런타임 환경 기본 호출 규칙을 지원하지 않습니다.
+
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+
+
The 'scoped' modifier cannot be used with discard.
'scoped' 한정자는 무시 항목과 함께 사용할 수 없습니다.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
index da459cc5b6389..a6a2606633b22 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
@@ -1457,6 +1457,11 @@
„{0}” nie jest prawidłową nazwą parametru z elementu „{1}”.
+
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+
+
The modifier '{0}' is not valid for this item in C# {1}. Please use language version '{2}' or greater.
Modyfikator „{0}” nie jest prawidłowy dla tego elementu w języku C# {1}. Użyj wersji języka „{2}” lub nowszej.
@@ -2357,6 +2362,11 @@
Docelowe środowisko uruchomieniowe nie obsługuje rozszerzalnych ani domyślnych dla środowiska uruchomieniowego konwencji wywoływania.
+
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+
+
The 'scoped' modifier cannot be used with discard.
Modyfikator „scoped” nie może być używany z odrzuceniem.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
index 90d782b7048e8..290835e6d52db 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
@@ -1457,6 +1457,11 @@
'{0}' não é um nome de parâmetro válido de '{1}'.
+
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+
+
The modifier '{0}' is not valid for this item in C# {1}. Please use language version '{2}' or greater.
O modificador '{0}' não é válido para este item no C# {1}. Use a versão de linguagem '{2}' ou superior.
@@ -2357,6 +2362,11 @@
O runtime de destino não dá suporte a convenções de chamada padrão extensíveis ou de ambiente de runtime.
+
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+
+
The 'scoped' modifier cannot be used with discard.
O modificador 'scoped' não pode ser usado com descarte.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
index 92e130f888c1a..dffd2877c6817 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
@@ -1457,6 +1457,11 @@
"{0}" не является допустимым именем параметра из "{1}".
+
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+
+
The modifier '{0}' is not valid for this item in C# {1}. Please use language version '{2}' or greater.
Модификатор "{0}" недопустим для этого элемента в C# {1}. Используйте версию языка "{2}" или более позднюю.
@@ -2357,6 +2362,11 @@
Целевая среда выполнения не поддерживает расширяемые или принадлежащие среде выполнения соглашения о вызовах по умолчанию.
+
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+
+
The 'scoped' modifier cannot be used with discard.
Модификатор "scoped" нельзя использовать с отменой.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
index 493f7e2a553b5..f6dfc9ffae25d 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
@@ -1457,6 +1457,11 @@
'{0}', '{1}' kaynağından geçerli bir parametre adı değil.
+
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+
+
The modifier '{0}' is not valid for this item in C# {1}. Please use language version '{2}' or greater.
'{0}' değiştiricisi bu öğe için C# {1} sürümünde geçerli değil. Lütfen '{2}' veya daha yüksek bir dil sürümü kullanın.
@@ -2357,6 +2362,11 @@
Hedef çalışma zamanı, genişletilebilir veya çalışma zamanı ortamı varsayılanı çağırma kurallarını desteklemiyor.
+
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+
+
The 'scoped' modifier cannot be used with discard.
'scoped' değiştiricisi atma ile kullanılamaz.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
index 9cb1579f6b145..e30d5f8dbc583 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
@@ -1457,6 +1457,11 @@
“{0}”不是来自“{1}”的有效参数名称。
+
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+
+
The modifier '{0}' is not valid for this item in C# {1}. Please use language version '{2}' or greater.
在 C# {1} 中,修饰符 "{0}" 对此项无效。请使用语言版本 "{2}" 或更高版本。
@@ -2357,6 +2362,11 @@
目标运行时不支持可扩展或运行时环境默认调用约定。
+
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+
+
The 'scoped' modifier cannot be used with discard.
"scoped" 修饰符不能与 discard 一起使用。
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
index e10aaee051992..f7c0dadf22036 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
@@ -1457,6 +1457,11 @@
'{0}' 不是來自 '{1}' 的有效參數名稱。
+
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+ The '{0}' modifier cannot immediately follow the 'scoped' modifier.
+
+
The modifier '{0}' is not valid for this item in C# {1}. Please use language version '{2}' or greater.
修飾元 '{0}' 在 C# {1} 中對此項目無效。請使用 '{2}' 或更高的語言版本。
@@ -2357,6 +2362,11 @@
目標執行階段不支援可延伸或執行階段環境的預設呼叫慣例。
+
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+
+
The 'scoped' modifier cannot be used with discard.
'scoped' 修飾元不能與捨棄一起使用。
diff --git a/src/Compilers/CSharp/Test/Emit3/RefReadonlyParameterTests.cs b/src/Compilers/CSharp/Test/Emit3/RefReadonlyParameterTests.cs
index e2865a72d1f5a..596e23a96d890 100644
--- a/src/Compilers/CSharp/Test/Emit3/RefReadonlyParameterTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/RefReadonlyParameterTests.cs
@@ -2146,15 +2146,9 @@ static class C
""";
var expectedDiagnostics = new[]
{
- // (3,30): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
+ // (3,30): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
// public static void M(ref scoped readonly int p) => throw null;
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 30),
- // (3,37): error CS1001: Identifier expected
- // public static void M(ref scoped readonly int p) => throw null;
- Diagnostic(ErrorCode.ERR_IdentifierExpected, "readonly").WithLocation(3, 37),
- // (3,37): error CS1003: Syntax error, ',' expected
- // public static void M(ref scoped readonly int p) => throw null;
- Diagnostic(ErrorCode.ERR_SyntaxError, "readonly").WithArguments(",").WithLocation(3, 37),
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(3, 30),
// (3,37): error CS9190: 'readonly' modifier must be specified after 'ref'.
// public static void M(ref scoped readonly int p) => throw null;
Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 37)
@@ -2178,16 +2172,7 @@ static class C
{
// (3,26): error CS9190: 'readonly' modifier must be specified after 'ref'.
// public static void M(readonly scoped ref int p) => throw null;
- Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 26),
- // (3,35): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
- // public static void M(readonly scoped ref int p) => throw null;
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 35),
- // (3,42): error CS1001: Identifier expected
- // public static void M(readonly scoped ref int p) => throw null;
- Diagnostic(ErrorCode.ERR_IdentifierExpected, "ref").WithLocation(3, 42),
- // (3,42): error CS1003: Syntax error, ',' expected
- // public static void M(readonly scoped ref int p) => throw null;
- Diagnostic(ErrorCode.ERR_SyntaxError, "ref").WithArguments(",").WithLocation(3, 42)
+ Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 26)
};
CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(expectedDiagnostics);
@@ -2206,15 +2191,12 @@ static class C
""";
var expectedDiagnostics = new[]
{
- // (3,26): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
- // public static void M(scoped readonly int p) => throw null;
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 26),
- // (3,33): error CS1001: Identifier expected
+ // (3,26): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
// public static void M(scoped readonly int p) => throw null;
- Diagnostic(ErrorCode.ERR_IdentifierExpected, "readonly").WithLocation(3, 33),
- // (3,33): error CS1003: Syntax error, ',' expected
+ Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped readonly int p").WithLocation(3, 26),
+ // (3,33): error CS9348: The 'readonly' modifier cannot immediately follow the 'scoped' modifier.
// public static void M(scoped readonly int p) => throw null;
- Diagnostic(ErrorCode.ERR_SyntaxError, "readonly").WithArguments(",").WithLocation(3, 33),
+ Diagnostic(ErrorCode.ERR_InvalidModifierAfterScoped, "readonly").WithArguments("readonly").WithLocation(3, 33),
// (3,33): error CS9190: 'readonly' modifier must be specified after 'ref'.
// public static void M(scoped readonly int p) => throw null;
Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(3, 33)
diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/ParamsCollectionTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/ParamsCollectionTests.cs
index 608dbdaf139d6..c94363eb2106e 100644
--- a/src/Compilers/CSharp/Test/Emit3/Semantics/ParamsCollectionTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/Semantics/ParamsCollectionTests.cs
@@ -17035,5 +17035,54 @@ .locals init (<>y__InlineArray4 V_0)
}
");
}
+
+ [Fact]
+ public void ScopedParams()
+ {
+ var source = """
+ using System.Collections;
+ using System.Collections.Generic;
+ ref struct S : IEnumerable
+ {
+ public void Add(int i) { }
+
+ public IEnumerator GetEnumerator() => throw null;
+ IEnumerator IEnumerable.GetEnumerator() => throw null;
+ }
+ static class C
+ {
+ public static void M(scoped params S x)
+ {
+ }
+ }
+ """;
+ CreateCompilation(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics(
+ // (12,33): error CS9348: The 'params' modifier cannot immediately follow the 'scoped' modifier.
+ // public static void M(scoped params S x)
+ Diagnostic(ErrorCode.ERR_InvalidModifierAfterScoped, "params").WithArguments("params").WithLocation(12, 33));
+ }
+
+ [Fact]
+ public void ParamsScoped()
+ {
+ var source = """
+ using System.Collections;
+ using System.Collections.Generic;
+ ref struct S : IEnumerable
+ {
+ public void Add(int i) { }
+
+ public IEnumerator GetEnumerator() => throw null;
+ IEnumerator IEnumerable.GetEnumerator() => throw null;
+ }
+ static class C
+ {
+ public static void M(params scoped S x)
+ {
+ }
+ }
+ """;
+ CreateCompilation(source, targetFramework: TargetFramework.Net90).VerifyDiagnostics();
+ }
}
}
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs
index d0f01f619f6d7..da22a01223836 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs
@@ -9396,5 +9396,73 @@ class ClassWithIntProperty : IWithIntProperty
x.IntProperty
");
}
+
+ [Fact]
+ public void TestMultipleScopedModifiers()
+ {
+ CreateCompilation("""
+ using System;
+ var v = (scoped scoped Span s) => { };
+ """,
+ targetFramework: TargetFramework.Net90).VerifyDiagnostics(
+ // (2,17): error CS1107: A parameter can only have one 'scoped' modifier
+ // var v = (scoped scoped Span s) => { };
+ Diagnostic(ErrorCode.ERR_DupParamMod, "scoped").WithArguments("scoped").WithLocation(2, 17));
+ }
+
+ [Fact]
+ public void TestMultipleRefModifiers()
+ {
+ CreateCompilation("""
+ using System;
+ var v = (ref ref Span s) => { };
+ """,
+ targetFramework: TargetFramework.Net90).VerifyDiagnostics(
+ // (2,14): error CS1107: A parameter can only have one 'ref' modifier
+ // var v = (ref ref Span s) => { };
+ Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(2, 14));
+ }
+
+ [Fact]
+ public void TestMultipleOutModifiers()
+ {
+ CreateCompilation("""
+ using System;
+ var v = (out out Span s) => { s = default; };
+ """,
+ targetFramework: TargetFramework.Net90).VerifyDiagnostics(
+ // (2,14): error CS1107: A parameter can only have one 'out' modifier
+ // var v = (out out Span s) => { s = default; };
+ Diagnostic(ErrorCode.ERR_DupParamMod, "out").WithArguments("out").WithLocation(2, 14));
+ }
+
+ [Fact]
+ public void TestMultipleInModifiers()
+ {
+ CreateCompilation("""
+ using System;
+ var v = (in in Span s) => { };
+ """,
+ targetFramework: TargetFramework.Net90).VerifyDiagnostics(
+ // (2,13): error CS1107: A parameter can only have one 'in' modifier
+ // var v = (in in Span s) => { };
+ Diagnostic(ErrorCode.ERR_DupParamMod, "in").WithArguments("in").WithLocation(2, 13));
+ }
+
+ [Fact]
+ public void TestMultipleReadonlyModifiers()
+ {
+ CreateCompilation("""
+ using System;
+ var v = (readonly readonly Span s) => { };
+ """,
+ targetFramework: TargetFramework.Net90).VerifyDiagnostics(
+ // (2,10): error CS9190: 'readonly' modifier must be specified after 'ref'.
+ // var v = (readonly readonly Span s) => { };
+ Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(2, 10),
+ // (2,19): error CS9190: 'readonly' modifier must be specified after 'ref'.
+ // var v = (readonly readonly Span s) => { };
+ Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(2, 19));
+ }
}
}
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs
index 4aea9bf02a2d8..725a1e993872e 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs
@@ -11327,24 +11327,15 @@ static void Main()
}";
var comp = CreateCompilation(source, parseOptions: TestOptions.Regular13);
comp.VerifyEmitDiagnostics(
- // (6,18): error CS8917: The delegate type could not be inferred.
+ // (6,26): error CS1107: A parameter can only have one 'scoped' modifier
// var f1 = (scoped scoped R r) => { };
- Diagnostic(ErrorCode.ERR_CannotInferDelegateType, "(scoped scoped R r) => { }").WithLocation(6, 18),
- // (6,26): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
- // var f1 = (scoped scoped R r) => { };
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(6, 26),
- // (6,35): error CS1003: Syntax error, ',' expected
- // var f1 = (scoped scoped R r) => { };
- Diagnostic(ErrorCode.ERR_SyntaxError, "r").WithArguments(",").WithLocation(6, 35),
- // (6,35): error CS0748: Inconsistent lambda parameter usage; parameter types must be all explicit or all implicit
- // var f1 = (scoped scoped R r) => { };
- Diagnostic(ErrorCode.ERR_InconsistentLambdaParameterUsage, "r").WithLocation(6, 35),
- // (7,23): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
+ Diagnostic(ErrorCode.ERR_DupParamMod, "scoped").WithArguments("scoped").WithLocation(6, 26),
+ // (7,23): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
// var f2 = (ref scoped scoped R r) => { };
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(7, 23),
- // (7,37): error CS1003: Syntax error, ',' expected
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(7, 23),
+ // (7,30): error CS1107: A parameter can only have one 'scoped' modifier
// var f2 = (ref scoped scoped R r) => { };
- Diagnostic(ErrorCode.ERR_SyntaxError, "R").WithArguments(",").WithLocation(7, 37),
+ Diagnostic(ErrorCode.ERR_DupParamMod, "scoped").WithArguments("scoped").WithLocation(7, 30),
// (8,19): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
// var f3 = (scoped scoped ref R r) => { };
Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(8, 19),
@@ -11371,33 +11362,18 @@ static void Main()
""";
var comp = CreateCompilation(source, parseOptions: TestOptions.Regular14);
comp.VerifyEmitDiagnostics(
- // (6,18): error CS8917: The delegate type could not be inferred.
- // var f1 = (scoped scoped R r) => { };
- Diagnostic(ErrorCode.ERR_CannotInferDelegateType, "(scoped scoped R r) => { }").WithLocation(6, 18),
- // (6,26): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
- // var f1 = (scoped scoped R r) => { };
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(6, 26),
- // (6,35): error CS1003: Syntax error, ',' expected
+ // (6,26): error CS1107: A parameter can only have one 'scoped' modifier
// var f1 = (scoped scoped R r) => { };
- Diagnostic(ErrorCode.ERR_SyntaxError, "r").WithArguments(",").WithLocation(6, 35),
- // (6,35): error CS0748: Inconsistent lambda parameter usage; parameter types must be all explicit or all implicit
- // var f1 = (scoped scoped R r) => { };
- Diagnostic(ErrorCode.ERR_InconsistentLambdaParameterUsage, "r").WithLocation(6, 35),
- // (7,23): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
+ Diagnostic(ErrorCode.ERR_DupParamMod, "scoped").WithArguments("scoped").WithLocation(6, 26),
+ // (7,23): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
// var f2 = (ref scoped scoped R r) => { };
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(7, 23),
- // (7,37): error CS1003: Syntax error, ',' expected
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(7, 23),
+ // (7,30): error CS1107: A parameter can only have one 'scoped' modifier
// var f2 = (ref scoped scoped R r) => { };
- Diagnostic(ErrorCode.ERR_SyntaxError, "R").WithArguments(",").WithLocation(7, 37),
- // (8,26): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
- // var f3 = (scoped scoped ref R r) => { };
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(8, 26),
- // (8,33): error CS1001: Identifier expected
+ Diagnostic(ErrorCode.ERR_DupParamMod, "scoped").WithArguments("scoped").WithLocation(7, 30),
+ // (8,26): error CS1107: A parameter can only have one 'scoped' modifier
// var f3 = (scoped scoped ref R r) => { };
- Diagnostic(ErrorCode.ERR_IdentifierExpected, "ref").WithLocation(8, 33),
- // (8,33): error CS1003: Syntax error, ',' expected
- // var f3 = (scoped scoped ref R r) => { };
- Diagnostic(ErrorCode.ERR_SyntaxError, "ref").WithArguments(",").WithLocation(8, 33));
+ Diagnostic(ErrorCode.ERR_DupParamMod, "scoped").WithArguments("scoped").WithLocation(8, 26));
}
[Fact]
@@ -11652,23 +11628,13 @@ static void F3(this scoped ref T t) where T : struct { }
}";
var comp = CreateCompilation(source);
comp.VerifyEmitDiagnostics(
- // (6,23): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
+ // (6,30): error CS9348: The 'this' modifier cannot immediately follow the 'scoped' modifier.
// static void F2(scoped this R r) { }
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(6, 23),
- // (6,30): error CS1001: Identifier expected
- // static void F2(scoped this R r) { }
- Diagnostic(ErrorCode.ERR_IdentifierExpected, "this").WithLocation(6, 30),
- // (6,30): error CS1003: Syntax error, ',' expected
- // static void F2(scoped this R r) { }
- Diagnostic(ErrorCode.ERR_SyntaxError, "this").WithArguments(",").WithLocation(6, 30),
- // (6,30): error CS1100: Method 'F2' has a parameter modifier 'this' which is not on the first parameter
- // static void F2(scoped this R r) { }
- Diagnostic(ErrorCode.ERR_BadThisParam, "this").WithArguments("F2").WithLocation(6, 30)
- );
+ Diagnostic(ErrorCode.ERR_InvalidModifierAfterScoped, "this").WithArguments("this").WithLocation(6, 30));
VerifyParameterSymbol(comp.GetMember("Extensions.F0").Parameters[0], "R r", RefKind.None, ScopedKind.None);
VerifyParameterSymbol(comp.GetMember("Extensions.F1").Parameters[0], "scoped R r", RefKind.None, ScopedKind.ScopedValue);
- VerifyParameterSymbol(comp.GetMember("Extensions.F2").Parameters[0], "scoped", RefKind.None, ScopedKind.None);
+ VerifyParameterSymbol(comp.GetMember("Extensions.F2").Parameters[0], "scoped R r", RefKind.None, ScopedKind.ScopedValue);
VerifyParameterSymbol(comp.GetMember("Extensions.F3").Parameters[0], "scoped ref T t", RefKind.Ref, ScopedKind.ScopedRef);
}
@@ -11789,10 +11755,9 @@ scoped readonly ref struct C { }
// (2,12): error CS1031: Type expected
// scoped ref struct B { }
Diagnostic(ErrorCode.ERR_TypeExpected, "struct").WithLocation(2, 12),
- // (3,8): error CS1585: Member modifier 'readonly' must precede the member type and name
+ // (3,1): error CS0116: A namespace cannot directly contain members such as fields, methods or statements
// scoped readonly ref struct C { }
- Diagnostic(ErrorCode.ERR_BadModifierLocation, "readonly").WithArguments("readonly").WithLocation(3, 8)
- );
+ Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "scoped").WithLocation(3, 1));
}
[Fact]
@@ -11817,9 +11782,9 @@ public void TypeScopeModifier_02_CSharp10()
// (1,15): error CS0548: '.A': property or indexer must have at least one accessor
// scoped record A { }
Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "A").WithArguments(".A").WithLocation(1, 15),
- // (2,8): error CS1585: Member modifier 'readonly' must precede the member type and name
+ // (2,1): error CS0116: A namespace cannot directly contain members such as fields, methods or statements
// scoped readonly record struct B;
- Diagnostic(ErrorCode.ERR_BadModifierLocation, "readonly").WithArguments("readonly").WithLocation(2, 8),
+ Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "scoped").WithLocation(2, 1),
// (3,1): error CS8803: Top-level statements must precede namespace and type declarations.
// readonly scoped record struct C();
Diagnostic(ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType, "readonly scoped record ").WithLocation(3, 1),
@@ -11837,8 +11802,7 @@ public void TypeScopeModifier_02_CSharp10()
Diagnostic(ErrorCode.ERR_SemicolonExpected, "struct").WithLocation(3, 24),
// (3,32): error CS8936: Feature 'primary constructors' is not available in C# 10.0. Please use language version 12.0 or greater.
// readonly scoped record struct C();
- Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "()").WithArguments("primary constructors", "12.0").WithLocation(3, 32)
- );
+ Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "()").WithArguments("primary constructors", "12.0").WithLocation(3, 32));
}
[Fact]
@@ -11863,9 +11827,9 @@ public void TypeScopeModifier_02_CSharp11()
// (1,15): error CS0548: '.A': property or indexer must have at least one accessor
// scoped record A { }
Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "A").WithArguments(".A").WithLocation(1, 15),
- // (2,8): error CS1585: Member modifier 'readonly' must precede the member type and name
+ // (2,1): error CS0116: A namespace cannot directly contain members such as fields, methods or statements
// scoped readonly record struct B;
- Diagnostic(ErrorCode.ERR_BadModifierLocation, "readonly").WithArguments("readonly").WithLocation(2, 8),
+ Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "scoped").WithLocation(2, 1),
// (3,1): error CS8803: Top-level statements must precede namespace and type declarations.
// readonly scoped record struct C();
Diagnostic(ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType, "readonly scoped record ").WithLocation(3, 1),
@@ -11883,8 +11847,7 @@ public void TypeScopeModifier_02_CSharp11()
Diagnostic(ErrorCode.ERR_SemicolonExpected, "struct").WithLocation(3, 24),
// (3,32): error CS9058: Feature 'primary constructors' is not available in C# 11.0. Please use language version 12.0 or greater.
// readonly scoped record struct C();
- Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "()").WithArguments("primary constructors", "12.0").WithLocation(3, 32)
- );
+ Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion11, "()").WithArguments("primary constructors", "12.0").WithLocation(3, 32));
}
[Fact]
@@ -21963,13 +21926,12 @@ public void RefScoped()
// (3,18): error CS1002: ; expected
// ref scoped R field;
Diagnostic(ErrorCode.ERR_SemicolonExpected, "field").WithLocation(3, 18),
- // (3,23): error CS1519: Invalid token ';' in class, record, struct, or interface member declaration
+ // (3,23): error CS1519: Invalid token ';' in a member declaration
// ref scoped R field;
Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(3, 23),
- // (3,23): error CS1519: Invalid token ';' in class, record, struct, or interface member declaration
+ // (3,23): error CS1519: Invalid token ';' in a member declaration
// ref scoped R field;
- Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(3, 23)
- );
+ Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(3, 23));
source =
@"ref struct R
@@ -22009,19 +21971,9 @@ void M(ref scoped R parameter)
}";
comp = CreateCompilation(source);
comp.VerifyDiagnostics(
- // (3,16): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
- // void M(ref scoped R parameter)
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 16),
- // (3,25): error CS1003: Syntax error, ',' expected
+ // (3,16): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
// void M(ref scoped R parameter)
- Diagnostic(ErrorCode.ERR_SyntaxError, "parameter").WithArguments(",").WithLocation(3, 25),
- // (3,25): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
- // void M(ref scoped R parameter)
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(3, 25),
- // (3,34): error CS1001: Identifier expected
- // void M(ref scoped R parameter)
- Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(3, 34)
- );
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(3, 16));
source =
@"ref struct R
@@ -22032,19 +21984,9 @@ void M(in scoped R parameter)
}";
comp = CreateCompilation(source);
comp.VerifyDiagnostics(
- // (3,15): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
- // void M(in scoped R parameter)
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 15),
- // (3,24): error CS1003: Syntax error, ',' expected
- // void M(in scoped R parameter)
- Diagnostic(ErrorCode.ERR_SyntaxError, "parameter").WithArguments(",").WithLocation(3, 24),
- // (3,24): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
+ // (3,15): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
// void M(in scoped R parameter)
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(3, 24),
- // (3,33): error CS1001: Identifier expected
- // void M(in scoped R parameter)
- Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(3, 33)
- );
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(3, 15));
source =
@"ref struct R
@@ -22055,22 +21997,9 @@ void M(out scoped R parameter)
}";
comp = CreateCompilation(source);
comp.VerifyDiagnostics(
- // (3,10): error CS0177: The out parameter 'R' must be assigned to before control leaves the current method
- // void M(out scoped R parameter)
- Diagnostic(ErrorCode.ERR_ParamUnassigned, "M").WithArguments("R").WithLocation(3, 10),
- // (3,16): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
- // void M(out scoped R parameter)
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 16),
- // (3,25): error CS1003: Syntax error, ',' expected
- // void M(out scoped R parameter)
- Diagnostic(ErrorCode.ERR_SyntaxError, "parameter").WithArguments(",").WithLocation(3, 25),
- // (3,25): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
+ // (3,16): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
// void M(out scoped R parameter)
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(3, 25),
- // (3,34): error CS1001: Identifier expected
- // void M(out scoped R parameter)
- Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(3, 34)
- );
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(3, 16));
source =
@"ref struct R
@@ -22081,13 +22010,12 @@ void M(ref scoped scoped R parameter)
}";
comp = CreateCompilation(source);
comp.VerifyDiagnostics(
- // (3,16): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
+ // (3,16): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
// void M(ref scoped scoped R parameter)
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(3, 16),
- // (3,30): error CS1003: Syntax error, ',' expected
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(3, 16),
+ // (3,23): error CS1107: A parameter can only have one 'scoped' modifier
// void M(ref scoped scoped R parameter)
- Diagnostic(ErrorCode.ERR_SyntaxError, "R").WithArguments(",").WithLocation(3, 30)
- );
+ Diagnostic(ErrorCode.ERR_DupParamMod, "scoped").WithArguments("scoped").WithLocation(3, 23));
source =
@"ref struct R
@@ -22190,19 +22118,9 @@ ref struct R { }
";
comp = CreateCompilation(source);
comp.VerifyDiagnostics(
- // (2,21): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
- // delegate void M(ref scoped R parameter);
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(2, 21),
- // (2,30): error CS1003: Syntax error, ',' expected
- // delegate void M(ref scoped R parameter);
- Diagnostic(ErrorCode.ERR_SyntaxError, "parameter").WithArguments(",").WithLocation(2, 30),
- // (2,30): error CS0246: The type or namespace name 'parameter' could not be found (are you missing a using directive or an assembly reference?)
+ // (2,21): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
// delegate void M(ref scoped R parameter);
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "parameter").WithArguments("parameter").WithLocation(2, 30),
- // (2,39): error CS1001: Identifier expected
- // delegate void M(ref scoped R parameter);
- Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(2, 39)
- );
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(2, 21));
source = @"
ref struct R
@@ -22218,15 +22136,9 @@ void M()
// (6,9): error CS8183: Cannot infer the type of implicitly-typed discard.
// _ = void (ref scoped R parameter) => throw null;
Diagnostic(ErrorCode.ERR_DiscardTypeInferenceFailed, "_").WithLocation(6, 9),
- // (6,23): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
- // _ = void (ref scoped R parameter) => throw null;
- Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(6, 23),
- // (6,32): error CS1003: Syntax error, ',' expected
- // _ = void (ref scoped R parameter) => throw null;
- Diagnostic(ErrorCode.ERR_SyntaxError, "parameter").WithArguments(",").WithLocation(6, 32),
- // (6,32): error CS0748: Inconsistent lambda parameter usage; parameter types must be all explicit or all implicit
+ // (6,23): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
// _ = void (ref scoped R parameter) => throw null;
- Diagnostic(ErrorCode.ERR_InconsistentLambdaParameterUsage, "parameter").WithLocation(6, 32));
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(6, 23));
}
[Theory, WorkItem(62931, "https://github.com/dotnet/roslyn/issues/62931")]
diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs
index d3c7a7e5fec53..60f2cd992fabb 100644
--- a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs
+++ b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs
@@ -19237,5 +19237,126 @@ struct C {
}
EOF();
}
+
+ [Fact]
+ public void ScopedInParameter1()
+ {
+ var text = """
+ static class C
+ {
+ public static void M(scoped in this int x) { }
+ }
+ """;
+ CreateCompilation(text).VerifyDiagnostics();
+
+ var tree = UsingTree(text);
+
+ N(SyntaxKind.CompilationUnit);
+ {
+ N(SyntaxKind.ClassDeclaration);
+ {
+ N(SyntaxKind.StaticKeyword);
+ N(SyntaxKind.ClassKeyword);
+ N(SyntaxKind.IdentifierToken, "C");
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.MethodDeclaration);
+ {
+ N(SyntaxKind.PublicKeyword);
+ N(SyntaxKind.StaticKeyword);
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.VoidKeyword);
+ }
+ N(SyntaxKind.IdentifierToken, "M");
+ N(SyntaxKind.ParameterList);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.Parameter);
+ {
+ N(SyntaxKind.ScopedKeyword);
+ N(SyntaxKind.InKeyword);
+ N(SyntaxKind.ThisKeyword);
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.IntKeyword);
+ }
+ N(SyntaxKind.IdentifierToken, "x");
+ }
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.Block);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ N(SyntaxKind.EndOfFileToken);
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void ScopedInParameter2()
+ {
+ var text = """
+ static class C
+ {
+ public static void M(this in scoped int x) { }
+ }
+ """;
+ CreateCompilation(text).VerifyDiagnostics(
+ // (3,34): error CS9349: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ // public static void M(this in scoped int x) { }
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(3, 34));
+
+ var tree = UsingTree(text);
+
+ N(SyntaxKind.CompilationUnit);
+ {
+ N(SyntaxKind.ClassDeclaration);
+ {
+ N(SyntaxKind.StaticKeyword);
+ N(SyntaxKind.ClassKeyword);
+ N(SyntaxKind.IdentifierToken, "C");
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.MethodDeclaration);
+ {
+ N(SyntaxKind.PublicKeyword);
+ N(SyntaxKind.StaticKeyword);
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.VoidKeyword);
+ }
+ N(SyntaxKind.IdentifierToken, "M");
+ N(SyntaxKind.ParameterList);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.Parameter);
+ {
+ N(SyntaxKind.ThisKeyword);
+ N(SyntaxKind.InKeyword);
+ N(SyntaxKind.ScopedKeyword);
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.IntKeyword);
+ }
+ N(SyntaxKind.IdentifierToken, "x");
+ }
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.Block);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ N(SyntaxKind.EndOfFileToken);
+ }
+ EOF();
+ }
}
}
diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationScopeParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationScopeParsingTests.cs
index 2af1953c35c0b..36c71ce0adb25 100644
--- a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationScopeParsingTests.cs
+++ b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationScopeParsingTests.cs
@@ -2,7 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
+using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
using Xunit.Abstractions;
@@ -133,32 +135,49 @@ public void Method_02(LanguageVersion langVersion)
EOF();
}
+ private static DiagnosticDescription[] FilterLanguageVersionChecks(LanguageVersion langVersion, params DiagnosticDescription[] expectedDiagnostics)
+ {
+ if (langVersion > LanguageVersion.CSharp10)
+ expectedDiagnostics = [.. expectedDiagnostics.Where(d => d.Code is not (int)ErrorCode.ERR_FeatureNotAvailableInVersion10)];
+
+ // Can add further filtering here if needed in future.
+
+ return expectedDiagnostics;
+ }
+
[Theory]
[InlineData(LanguageVersion.CSharp10)]
[InlineData(LanguageVersion.CSharp11)]
public void Method_03(LanguageVersion langVersion)
{
string source = "void F(ref scoped int b, in scoped int c, out scoped int d) { }";
- UsingDeclaration(source, TestOptions.Regular.WithLanguageVersion(langVersion),
- // (1,19): error CS1001: Identifier expected
- // void F(ref scoped int b, in scoped int c, out scoped int d) { }
- Diagnostic(ErrorCode.ERR_IdentifierExpected, "int").WithLocation(1, 19),
- // (1,19): error CS1003: Syntax error, ',' expected
- // void F(ref scoped int b, in scoped int c, out scoped int d) { }
- Diagnostic(ErrorCode.ERR_SyntaxError, "int").WithArguments(",").WithLocation(1, 19),
- // (1,36): error CS1001: Identifier expected
- // void F(ref scoped int b, in scoped int c, out scoped int d) { }
- Diagnostic(ErrorCode.ERR_IdentifierExpected, "int").WithLocation(1, 36),
- // (1,36): error CS1003: Syntax error, ',' expected
- // void F(ref scoped int b, in scoped int c, out scoped int d) { }
- Diagnostic(ErrorCode.ERR_SyntaxError, "int").WithArguments(",").WithLocation(1, 36),
- // (1,54): error CS1001: Identifier expected
- // void F(ref scoped int b, in scoped int c, out scoped int d) { }
- Diagnostic(ErrorCode.ERR_IdentifierExpected, "int").WithLocation(1, 54),
- // (1,54): error CS1003: Syntax error, ',' expected
- // void F(ref scoped int b, in scoped int c, out scoped int d) { }
- Diagnostic(ErrorCode.ERR_SyntaxError, "int").WithArguments(",").WithLocation(1, 54)
- );
+ UsingDeclaration(source, TestOptions.Regular.WithLanguageVersion(langVersion));
+ CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
+ FilterLanguageVersionChecks(langVersion,
+ // (1,6): error CS0177: The out parameter 'd' must be assigned to before control leaves the current method
+ // void F(ref scoped int b, in scoped int c, out scoped int d) { }
+ Diagnostic(ErrorCode.ERR_ParamUnassigned, "F").WithArguments("d").WithLocation(1, 6),
+ // (1,6): warning CS8321: The local function 'F' is declared but never used
+ // void F(ref scoped int b, in scoped int c, out scoped int d) { }
+ Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "F").WithArguments("F").WithLocation(1, 6),
+ // (1,12): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
+ // void F(ref scoped int b, in scoped int c, out scoped int d) { }
+ Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(1, 12),
+ // (1,12): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ // void F(ref scoped int b, in scoped int c, out scoped int d) { }
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(1, 12),
+ // (1,29): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
+ // void F(ref scoped int b, in scoped int c, out scoped int d) { }
+ Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(1, 29),
+ // (1,29): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ // void F(ref scoped int b, in scoped int c, out scoped int d) { }
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(1, 29),
+ // (1,47): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
+ // void F(ref scoped int b, in scoped int c, out scoped int d) { }
+ Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(1, 47),
+ // (1,47): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ // void F(ref scoped int b, in scoped int c, out scoped int d) { }
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(1, 47)));
N(SyntaxKind.MethodDeclaration);
{
@@ -173,15 +192,7 @@ public void Method_03(LanguageVersion langVersion)
N(SyntaxKind.Parameter);
{
N(SyntaxKind.RefKeyword);
- N(SyntaxKind.IdentifierName);
- {
- N(SyntaxKind.IdentifierToken, "scoped");
- }
- M(SyntaxKind.IdentifierToken);
- }
- M(SyntaxKind.CommaToken);
- N(SyntaxKind.Parameter);
- {
+ N(SyntaxKind.ScopedKeyword);
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.IntKeyword);
@@ -192,15 +203,7 @@ public void Method_03(LanguageVersion langVersion)
N(SyntaxKind.Parameter);
{
N(SyntaxKind.InKeyword);
- N(SyntaxKind.IdentifierName);
- {
- N(SyntaxKind.IdentifierToken, "scoped");
- }
- M(SyntaxKind.IdentifierToken);
- }
- M(SyntaxKind.CommaToken);
- N(SyntaxKind.Parameter);
- {
+ N(SyntaxKind.ScopedKeyword);
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.IntKeyword);
@@ -211,15 +214,7 @@ public void Method_03(LanguageVersion langVersion)
N(SyntaxKind.Parameter);
{
N(SyntaxKind.OutKeyword);
- N(SyntaxKind.IdentifierName);
- {
- N(SyntaxKind.IdentifierToken, "scoped");
- }
- M(SyntaxKind.IdentifierToken);
- }
- M(SyntaxKind.CommaToken);
- N(SyntaxKind.Parameter);
- {
+ N(SyntaxKind.ScopedKeyword);
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.IntKeyword);
@@ -564,11 +559,20 @@ public void Method_07()
public void Method_08()
{
string source = "void F(ref scoped scoped R r) { }";
- UsingDeclaration(source, TestOptions.Regular11,
- // (1,26): error CS1003: Syntax error, ',' expected
+ UsingDeclaration(source, TestOptions.Regular11);
+ CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
+ // (1,6): warning CS8321: The local function 'F' is declared but never used
// void F(ref scoped scoped R r) { }
- Diagnostic(ErrorCode.ERR_SyntaxError, "R").WithArguments(",").WithLocation(1, 26)
- );
+ Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "F").WithArguments("F").WithLocation(1, 6),
+ // (1,12): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ // void F(ref scoped scoped R r) { }
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(1, 12),
+ // (1,19): error CS1107: A parameter can only have one 'scoped' modifier
+ // void F(ref scoped scoped R r) { }
+ Diagnostic(ErrorCode.ERR_DupParamMod, "scoped").WithArguments("scoped").WithLocation(1, 19),
+ // (1,26): error CS0246: The type or namespace name 'R' could not be found (are you missing a using directive or an assembly reference?)
+ // void F(ref scoped scoped R r) { }
+ Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "R").WithArguments("R").WithLocation(1, 26));
N(SyntaxKind.MethodDeclaration);
{
@@ -583,15 +587,8 @@ public void Method_08()
N(SyntaxKind.Parameter);
{
N(SyntaxKind.RefKeyword);
- N(SyntaxKind.IdentifierName);
- {
- N(SyntaxKind.IdentifierToken, "scoped");
- }
- N(SyntaxKind.IdentifierToken, "scoped");
- }
- M(SyntaxKind.CommaToken);
- N(SyntaxKind.Parameter);
- {
+ N(SyntaxKind.ScopedKeyword);
+ N(SyntaxKind.ScopedKeyword);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "R");
@@ -615,14 +612,36 @@ public void Method_08()
public void Method_09(LanguageVersion langVersion)
{
string source = "void F(scoped scoped x, ref scoped y, ref scoped scoped z, scoped ref scoped w) { }";
- UsingDeclaration(source, TestOptions.Regular.WithLanguageVersion(langVersion),
- // (1,57): error CS1003: Syntax error, ',' expected
- // void F(scoped scoped x, ref scoped y, ref scoped scoped z, scoped ref scoped w) { }
- Diagnostic(ErrorCode.ERR_SyntaxError, "z").WithArguments(",").WithLocation(1, 57),
- // (1,58): error CS1001: Identifier expected
- // void F(scoped scoped x, ref scoped y, ref scoped scoped z, scoped ref scoped w) { }
- Diagnostic(ErrorCode.ERR_IdentifierExpected, ",").WithLocation(1, 58)
- );
+ UsingDeclaration(source, TestOptions.Regular.WithLanguageVersion(langVersion));
+ CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
+ FilterLanguageVersionChecks(langVersion,
+ // (1,6): warning CS8321: The local function 'F' is declared but never used
+ // void F(scoped scoped x, ref scoped y, ref scoped scoped z, scoped ref scoped w) { }
+ Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "F").WithArguments("F").WithLocation(1, 6),
+ // (1,8): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
+ // void F(scoped scoped x, ref scoped y, ref scoped scoped z, scoped ref scoped w) { }
+ Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(1, 8),
+ // (1,15): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
+ // void F(scoped scoped x, ref scoped y, ref scoped scoped z, scoped ref scoped w) { }
+ Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(1, 15),
+ // (1,29): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
+ // void F(scoped scoped x, ref scoped y, ref scoped scoped z, scoped ref scoped w) { }
+ Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(1, 29),
+ // (1,43): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
+ // void F(scoped scoped x, ref scoped y, ref scoped scoped z, scoped ref scoped w) { }
+ Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(1, 43),
+ // (1,43): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ // void F(scoped scoped x, ref scoped y, ref scoped scoped z, scoped ref scoped w) { }
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(1, 43),
+ // (1,50): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
+ // void F(scoped scoped x, ref scoped y, ref scoped scoped z, scoped ref scoped w) { }
+ Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(1, 50),
+ // (1,60): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
+ // void F(scoped scoped x, ref scoped y, ref scoped scoped z, scoped ref scoped w) { }
+ Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(1, 60),
+ // (1,71): error CS0246: The type or namespace name 'scoped' could not be found (are you missing a using directive or an assembly reference?)
+ // void F(scoped scoped x, ref scoped y, ref scoped scoped z, scoped ref scoped w) { }
+ Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "scoped").WithArguments("scoped").WithLocation(1, 71)));
N(SyntaxKind.MethodDeclaration);
{
@@ -657,20 +676,12 @@ public void Method_09(LanguageVersion langVersion)
N(SyntaxKind.Parameter);
{
N(SyntaxKind.RefKeyword);
+ N(SyntaxKind.ScopedKeyword);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "scoped");
}
- N(SyntaxKind.IdentifierToken, "scoped");
- }
- M(SyntaxKind.CommaToken);
- N(SyntaxKind.Parameter);
- {
- N(SyntaxKind.IdentifierName);
- {
- N(SyntaxKind.IdentifierToken, "z");
- }
- M(SyntaxKind.IdentifierToken);
+ N(SyntaxKind.IdentifierToken, "z");
}
N(SyntaxKind.CommaToken);
N(SyntaxKind.Parameter);
@@ -763,14 +774,24 @@ public void Method_10(LanguageVersion langVersion)
public void Method_11(LanguageVersion langVersion)
{
string source = "void F(scoped readonly int a) { }";
- UsingDeclaration(source, TestOptions.Regular.WithLanguageVersion(langVersion),
- // (1,15): error CS1001: Identifier expected
- // void F(scoped readonly int a) { }
- Diagnostic(ErrorCode.ERR_IdentifierExpected, "readonly").WithLocation(1, 15),
- // (1,15): error CS1003: Syntax error, ',' expected
- // void F(scoped readonly int a) { }
- Diagnostic(ErrorCode.ERR_SyntaxError, "readonly").WithArguments(",").WithLocation(1, 15)
- );
+ UsingDeclaration(source, TestOptions.Regular.WithLanguageVersion(langVersion));
+ CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
+ FilterLanguageVersionChecks(langVersion,
+ // (1,6): warning CS8321: The local function 'F' is declared but never used
+ // void F(scoped readonly int a) { }
+ Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "F").WithArguments("F").WithLocation(1, 6),
+ // (1,8): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
+ // void F(scoped readonly int a) { }
+ Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(1, 8),
+ // (1,8): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
+ // void F(scoped readonly int a) { }
+ Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped readonly int a").WithLocation(1, 8),
+ // (1,15): error CS9348: The 'readonly' modifier cannot immediately follow the 'scoped' modifier.
+ // void F(scoped readonly int a) { }
+ Diagnostic(ErrorCode.ERR_InvalidModifierAfterScoped, "readonly").WithArguments("readonly").WithLocation(1, 15),
+ // (1,15): error CS9190: 'readonly' modifier must be specified after 'ref'.
+ // void F(scoped readonly int a) { }
+ Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(1, 15)));
N(SyntaxKind.MethodDeclaration);
{
@@ -784,15 +805,7 @@ public void Method_11(LanguageVersion langVersion)
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
- N(SyntaxKind.IdentifierName);
- {
- N(SyntaxKind.IdentifierToken, "scoped");
- }
- M(SyntaxKind.IdentifierToken);
- }
- M(SyntaxKind.CommaToken);
- N(SyntaxKind.Parameter);
- {
+ N(SyntaxKind.ScopedKeyword);
N(SyntaxKind.ReadOnlyKeyword);
N(SyntaxKind.PredefinedType);
{
@@ -857,14 +870,24 @@ public void Method_12(LanguageVersion langVersion)
public void Method_13(LanguageVersion langVersion)
{
string source = "void F(out scoped ref int a) { }";
- UsingDeclaration(source, TestOptions.Regular.WithLanguageVersion(langVersion),
- // (1,19): error CS1001: Identifier expected
- // void F(out scoped ref int a) { }
- Diagnostic(ErrorCode.ERR_IdentifierExpected, "ref").WithLocation(1, 19),
- // (1,19): error CS1003: Syntax error, ',' expected
- // void F(out scoped ref int a) { }
- Diagnostic(ErrorCode.ERR_SyntaxError, "ref").WithArguments(",").WithLocation(1, 19)
- );
+ UsingDeclaration(source, TestOptions.Regular.WithLanguageVersion(langVersion));
+ CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
+ FilterLanguageVersionChecks(langVersion,
+ // (1,6): error CS0177: The out parameter 'a' must be assigned to before control leaves the current method
+ // void F(out scoped ref int a) { }
+ Diagnostic(ErrorCode.ERR_ParamUnassigned, "F").WithArguments("a").WithLocation(1, 6),
+ // (1,6): warning CS8321: The local function 'F' is declared but never used
+ // void F(out scoped ref int a) { }
+ Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "F").WithArguments("F").WithLocation(1, 6),
+ // (1,12): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
+ // void F(out scoped ref int a) { }
+ Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(1, 12),
+ // (1,12): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ // void F(out scoped ref int a) { }
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(1, 12),
+ // (1,19): error CS8328: The parameter modifier 'ref' cannot be used with 'out'
+ // void F(out scoped ref int a) { }
+ Diagnostic(ErrorCode.ERR_BadParameterModifiers, "ref").WithArguments("ref", "out").WithLocation(1, 19)));
N(SyntaxKind.MethodDeclaration);
{
@@ -879,15 +902,7 @@ public void Method_13(LanguageVersion langVersion)
N(SyntaxKind.Parameter);
{
N(SyntaxKind.OutKeyword);
- N(SyntaxKind.IdentifierName);
- {
- N(SyntaxKind.IdentifierToken, "scoped");
- }
- M(SyntaxKind.IdentifierToken);
- }
- M(SyntaxKind.CommaToken);
- N(SyntaxKind.Parameter);
- {
+ N(SyntaxKind.ScopedKeyword);
N(SyntaxKind.RefKeyword);
N(SyntaxKind.PredefinedType);
{
@@ -1020,30 +1035,41 @@ public void Lambda_02(LanguageVersion langVersion)
public void Lambda_03_Ref(LanguageVersion langVersion)
{
string source = "(ref scoped int a) => null";
- UsingExpression(source, TestOptions.Regular.WithLanguageVersion(langVersion),
- // (1,1): error CS1073: Unexpected token 'int'
- // (ref scoped int a) => null
- Diagnostic(ErrorCode.ERR_UnexpectedToken, "(ref scoped ").WithArguments("int").WithLocation(1, 1),
- // (1,2): error CS1525: Invalid expression term 'ref'
- // (ref scoped int a) => null
- Diagnostic(ErrorCode.ERR_InvalidExprTerm, "ref scoped").WithArguments("ref").WithLocation(1, 2),
- // (1,13): error CS1026: ) expected
- // (ref scoped int a) => null
- Diagnostic(ErrorCode.ERR_CloseParenExpected, "int").WithLocation(1, 13)
- );
+ UsingExpression(source, TestOptions.Regular.WithLanguageVersion(langVersion));
+ CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
+ FilterLanguageVersionChecks(langVersion,
+ // (1,6): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
+ // (ref scoped int a) => null
+ Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(1, 6),
+ // (1,6): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ // (ref scoped int a) => null
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(1, 6),
+ // (1,27): error CS1002: ; expected
+ // (ref scoped int a) => null
+ Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(1, 27)));
- N(SyntaxKind.ParenthesizedExpression);
+ N(SyntaxKind.ParenthesizedLambdaExpression);
{
- N(SyntaxKind.OpenParenToken);
- N(SyntaxKind.RefExpression);
+ N(SyntaxKind.ParameterList);
{
- N(SyntaxKind.RefKeyword);
- N(SyntaxKind.IdentifierName);
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.Parameter);
{
- N(SyntaxKind.IdentifierToken, "scoped");
+ N(SyntaxKind.RefKeyword);
+ N(SyntaxKind.ScopedKeyword);
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.IntKeyword);
+ }
+ N(SyntaxKind.IdentifierToken, "a");
}
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.EqualsGreaterThanToken);
+ N(SyntaxKind.NullLiteralExpression);
+ {
+ N(SyntaxKind.NullKeyword);
}
- M(SyntaxKind.CloseParenToken);
}
EOF();
}
@@ -1054,26 +1080,41 @@ public void Lambda_03_Ref(LanguageVersion langVersion)
public void Lambda_03_In(LanguageVersion langVersion)
{
string source = "(in scoped int a) => null";
- UsingExpression(source, TestOptions.Regular.WithLanguageVersion(langVersion),
- // (1,1): error CS1073: Unexpected token 'in'
- // (in scoped int a) => null
- Diagnostic(ErrorCode.ERR_UnexpectedToken, "(").WithArguments("in").WithLocation(1, 1),
- // (1,2): error CS1525: Invalid expression term 'in'
- // (in scoped int a) => null
- Diagnostic(ErrorCode.ERR_InvalidExprTerm, "in").WithArguments("in").WithLocation(1, 2),
- // (1,2): error CS1026: ) expected
- // (in scoped int a) => null
- Diagnostic(ErrorCode.ERR_CloseParenExpected, "in").WithLocation(1, 2)
- );
+ UsingExpression(source, TestOptions.Regular.WithLanguageVersion(langVersion));
+ CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
+ FilterLanguageVersionChecks(langVersion,
+ // (1,5): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
+ // (in scoped int a) => null
+ Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(1, 5),
+ // (1,5): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ // (in scoped int a) => null
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(1, 5),
+ // (1,26): error CS1002: ; expected
+ // (in scoped int a) => null
+ Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(1, 26)));
- N(SyntaxKind.ParenthesizedExpression);
+ N(SyntaxKind.ParenthesizedLambdaExpression);
{
- N(SyntaxKind.OpenParenToken);
- M(SyntaxKind.IdentifierName);
+ N(SyntaxKind.ParameterList);
{
- M(SyntaxKind.IdentifierToken);
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.Parameter);
+ {
+ N(SyntaxKind.InKeyword);
+ N(SyntaxKind.ScopedKeyword);
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.IntKeyword);
+ }
+ N(SyntaxKind.IdentifierToken, "a");
+ }
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.EqualsGreaterThanToken);
+ N(SyntaxKind.NullLiteralExpression);
+ {
+ N(SyntaxKind.NullKeyword);
}
- M(SyntaxKind.CloseParenToken);
}
EOF();
}
@@ -1084,26 +1125,44 @@ public void Lambda_03_In(LanguageVersion langVersion)
public void Lambda_03_Out(LanguageVersion langVersion)
{
string source = "(out scoped int a) => null";
- UsingExpression(source, TestOptions.Regular.WithLanguageVersion(langVersion),
- // (1,1): error CS1073: Unexpected token 'out'
- // (out scoped int a) => null
- Diagnostic(ErrorCode.ERR_UnexpectedToken, "(").WithArguments("out").WithLocation(1, 1),
- // (1,2): error CS1525: Invalid expression term 'out'
- // (out scoped int a) => null
- Diagnostic(ErrorCode.ERR_InvalidExprTerm, "out").WithArguments("out").WithLocation(1, 2),
- // (1,2): error CS1026: ) expected
- // (out scoped int a) => null
- Diagnostic(ErrorCode.ERR_CloseParenExpected, "out").WithLocation(1, 2)
- );
+ UsingExpression(source, TestOptions.Regular.WithLanguageVersion(langVersion));
+ CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
+ FilterLanguageVersionChecks(langVersion,
+ // (1,6): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
+ // (out scoped int a) => null
+ Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(1, 6),
+ // (1,6): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ // (out scoped int a) => null
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(1, 6),
+ // (1,23): error CS0177: The out parameter 'a' must be assigned to before control leaves the current method
+ // (out scoped int a) => null
+ Diagnostic(ErrorCode.ERR_ParamUnassigned, "null").WithArguments("a").WithLocation(1, 23),
+ // (1,27): error CS1002: ; expected
+ // (out scoped int a) => null
+ Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(1, 27)));
- N(SyntaxKind.ParenthesizedExpression);
+ N(SyntaxKind.ParenthesizedLambdaExpression);
{
- N(SyntaxKind.OpenParenToken);
- M(SyntaxKind.IdentifierName);
+ N(SyntaxKind.ParameterList);
{
- M(SyntaxKind.IdentifierToken);
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.Parameter);
+ {
+ N(SyntaxKind.OutKeyword);
+ N(SyntaxKind.ScopedKeyword);
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.IntKeyword);
+ }
+ N(SyntaxKind.IdentifierToken, "a");
+ }
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.EqualsGreaterThanToken);
+ N(SyntaxKind.NullLiteralExpression);
+ {
+ N(SyntaxKind.NullKeyword);
}
- M(SyntaxKind.CloseParenToken);
}
EOF();
}
@@ -1181,10 +1240,20 @@ public void Lambda_05()
public void Lambda_06()
{
string source = "(ref scoped scoped R r) => { }";
- UsingExpression(source, TestOptions.Regular11,
- // (1,20): error CS1003: Syntax error, ',' expected
+ UsingExpression(source, TestOptions.Regular11);
+ CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
+ // (1,6): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ // (ref scoped scoped R r) => { }
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(1, 6),
+ // (1,13): error CS1107: A parameter can only have one 'scoped' modifier
// (ref scoped scoped R r) => { }
- Diagnostic(ErrorCode.ERR_SyntaxError, "R").WithArguments(",").WithLocation(1, 20));
+ Diagnostic(ErrorCode.ERR_DupParamMod, "scoped").WithArguments("scoped").WithLocation(1, 13),
+ // (1,20): error CS0246: The type or namespace name 'R' could not be found (are you missing a using directive or an assembly reference?)
+ // (ref scoped scoped R r) => { }
+ Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "R").WithArguments("R").WithLocation(1, 20),
+ // (1,31): error CS1002: ; expected
+ // (ref scoped scoped R r) => { }
+ Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(1, 31));
N(SyntaxKind.ParenthesizedLambdaExpression);
{
@@ -1194,15 +1263,8 @@ public void Lambda_06()
N(SyntaxKind.Parameter);
{
N(SyntaxKind.RefKeyword);
- N(SyntaxKind.IdentifierName);
- {
- N(SyntaxKind.IdentifierToken, "scoped");
- }
- N(SyntaxKind.IdentifierToken, "scoped");
- }
- M(SyntaxKind.CommaToken);
- N(SyntaxKind.Parameter);
- {
+ N(SyntaxKind.ScopedKeyword);
+ N(SyntaxKind.ScopedKeyword);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "R");
@@ -1321,14 +1383,20 @@ public void Lambda_08(LanguageVersion langVersion)
public void Params_01()
{
string source = "void F(scoped params object[] args);";
- UsingDeclaration(source, TestOptions.Regular11,
- // (1,15): error CS1001: Identifier expected
+ UsingDeclaration(source, TestOptions.Regular11);
+ CreateCompilation(source, parseOptions: TestOptions.Regular11).VerifyDiagnostics(
+ // (1,6): error CS8112: Local function 'F(params scoped object[])' must declare a body because it is not marked 'static extern'.
// void F(scoped params object[] args);
- Diagnostic(ErrorCode.ERR_IdentifierExpected, "params").WithLocation(1, 15),
- // (1,15): error CS1003: Syntax error, ',' expected
+ Diagnostic(ErrorCode.ERR_LocalFunctionMissingBody, "F").WithArguments("F(params scoped object[])").WithLocation(1, 6),
+ // (1,6): warning CS8321: The local function 'F' is declared but never used
// void F(scoped params object[] args);
- Diagnostic(ErrorCode.ERR_SyntaxError, "params").WithArguments(",").WithLocation(1, 15)
- );
+ Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "F").WithArguments("F").WithLocation(1, 6),
+ // (1,8): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
+ // void F(scoped params object[] args);
+ Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped params object[] args").WithLocation(1, 8),
+ // (1,15): error CS9348: The 'params' modifier cannot immediately follow the 'scoped' modifier.
+ // void F(scoped params object[] args);
+ Diagnostic(ErrorCode.ERR_InvalidModifierAfterScoped, "params").WithArguments("params").WithLocation(1, 15));
N(SyntaxKind.MethodDeclaration);
{
@@ -1342,15 +1410,7 @@ public void Params_01()
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
- N(SyntaxKind.IdentifierName);
- {
- N(SyntaxKind.IdentifierToken, "scoped");
- }
- M(SyntaxKind.IdentifierToken);
- }
- M(SyntaxKind.CommaToken);
- N(SyntaxKind.Parameter);
- {
+ N(SyntaxKind.ScopedKeyword);
N(SyntaxKind.ParamsKeyword);
N(SyntaxKind.ArrayType);
{
@@ -9616,11 +9676,29 @@ public void FunctionPointer_01(LanguageVersion langVersion)
public void FunctionPointer_02(LanguageVersion langVersion)
{
string source = @"delegate* f;";
- UsingStatement(source, TestOptions.Regular.WithLanguageVersion(langVersion),
- // (1,32): error CS1003: Syntax error, ',' expected
+ UsingStatement(source, TestOptions.Regular.WithLanguageVersion(langVersion));
+ CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(langVersion)).VerifyDiagnostics(
+ // (1,1): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context
// delegate* f;
- Diagnostic(ErrorCode.ERR_SyntaxError, "R").WithArguments(",").WithLocation(1, 32)
- );
+ Diagnostic(ErrorCode.ERR_UnsafeNeeded, "delegate*").WithLocation(1, 1),
+ // (1,11): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
+ // delegate* f;
+ Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(1, 11),
+ // (1,18): error CS0246: The type or namespace name 'R' could not be found (are you missing a using directive or an assembly reference?)
+ // delegate* f;
+ Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "R").WithArguments("R").WithLocation(1, 18),
+ // (1,25): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
+ // delegate* f;
+ Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(1, 25),
+ // (1,32): error CS0246: The type or namespace name 'R' could not be found (are you missing a using directive or an assembly reference?)
+ // delegate* f;
+ Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "R").WithArguments("R").WithLocation(1, 32),
+ // (1,35): error CS8755: 'scoped' cannot be used as a modifier on a function pointer parameter.
+ // delegate* f;
+ Diagnostic(ErrorCode.ERR_BadFuncPointerParamModifier, "scoped").WithArguments("scoped").WithLocation(1, 35),
+ // (1,57): warning CS0168: The variable 'f' is declared but never used
+ // delegate* f;
+ Diagnostic(ErrorCode.WRN_UnreferencedVar, "f").WithArguments("f").WithLocation(1, 57));
N(SyntaxKind.LocalDeclarationStatement);
{
@@ -9645,9 +9723,10 @@ public void FunctionPointer_02(LanguageVersion langVersion)
N(SyntaxKind.FunctionPointerParameter);
{
N(SyntaxKind.RefKeyword);
+ N(SyntaxKind.ScopedKeyword);
N(SyntaxKind.IdentifierName);
{
- N(SyntaxKind.IdentifierToken, "scoped");
+ N(SyntaxKind.IdentifierToken, "R");
}
}
N(SyntaxKind.CommaToken);
@@ -11218,9 +11297,9 @@ public void Type_02()
readonly scoped record struct C();
";
UsingTree(source, TestOptions.Regular11,
- // (2,8): error CS1585: Member modifier 'readonly' must precede the member type and name
+ // (2,1): error CS0116: A namespace cannot directly contain members such as fields, methods or statements
// scoped readonly record struct B;
- Diagnostic(ErrorCode.ERR_BadModifierLocation, "readonly").WithArguments("readonly").WithLocation(2, 8),
+ Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "scoped").WithLocation(2, 1),
// (3,1): error CS8803: Top-level statements must precede namespace and type declarations.
// readonly scoped record struct C();
Diagnostic(ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType, "readonly scoped record ").WithLocation(3, 1),
@@ -11229,8 +11308,7 @@ public void Type_02()
Diagnostic(ErrorCode.ERR_BadMemberFlag, "readonly").WithArguments("readonly").WithLocation(3, 1),
// (3,24): error CS1002: ; expected
// readonly scoped record struct C();
- Diagnostic(ErrorCode.ERR_SemicolonExpected, "struct").WithLocation(3, 24)
- );
+ Diagnostic(ErrorCode.ERR_SemicolonExpected, "struct").WithLocation(3, 24));
N(SyntaxKind.CompilationUnit);
{
@@ -11250,10 +11328,7 @@ public void Type_02()
}
N(SyntaxKind.IncompleteMember);
{
- N(SyntaxKind.IdentifierName);
- {
- N(SyntaxKind.IdentifierToken, "scoped");
- }
+ N(SyntaxKind.ScopedKeyword);
}
N(SyntaxKind.RecordStructDeclaration);
{
diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/LambdaParameterParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/LambdaParameterParsingTests.cs
index 310422247bdb6..2061d999dc23f 100644
--- a/src/Compilers/CSharp/Test/Syntax/Parsing/LambdaParameterParsingTests.cs
+++ b/src/Compilers/CSharp/Test/Syntax/Parsing/LambdaParameterParsingTests.cs
@@ -5759,7 +5759,7 @@ public void ScopedAsParameterName_05()
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63469")]
- public void ScopedAsParameterName_06_CSharp13()
+ public void ScopedAsParameterName_06_CSharp13_A()
{
string source = "(scoped scoped) => { }";
UsingExpression(source, TestOptions.Regular13);
@@ -5790,7 +5790,86 @@ public void ScopedAsParameterName_06_CSharp13()
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63469")]
- public void ScopedAsParameterName_06_Preview()
+ public void ScopedAsParameterName_06_CSharp13_B()
+ {
+ string source = "(scoped scoped, int i) => { }";
+ UsingExpression(source, TestOptions.Regular13);
+
+ N(SyntaxKind.ParenthesizedLambdaExpression);
+ {
+ N(SyntaxKind.ParameterList);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.Parameter);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "scoped");
+ }
+ N(SyntaxKind.IdentifierToken, "scoped");
+ }
+ N(SyntaxKind.CommaToken);
+ N(SyntaxKind.Parameter);
+ {
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.IntKeyword);
+ }
+ N(SyntaxKind.IdentifierToken, "i");
+ }
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.EqualsGreaterThanToken);
+ N(SyntaxKind.Block);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ EOF();
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63469")]
+ public void ScopedAsParameterName_06_CSharp13_C()
+ {
+ string source = "(scoped scoped = default) => { }";
+ UsingExpression(source, TestOptions.Regular13);
+
+ N(SyntaxKind.ParenthesizedLambdaExpression);
+ {
+ N(SyntaxKind.ParameterList);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.Parameter);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "scoped");
+ }
+ N(SyntaxKind.IdentifierToken, "scoped");
+ N(SyntaxKind.EqualsValueClause);
+ {
+ N(SyntaxKind.EqualsToken);
+ N(SyntaxKind.DefaultLiteralExpression);
+ {
+ N(SyntaxKind.DefaultKeyword);
+ }
+ }
+ }
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.EqualsGreaterThanToken);
+ N(SyntaxKind.Block);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ EOF();
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63469")]
+ public void ScopedAsParameterName_06_Preview_A()
{
string source = "(scoped scoped) => { }";
UsingExpression(source, TestOptions.RegularPreview);
@@ -5817,6 +5896,79 @@ public void ScopedAsParameterName_06_Preview()
EOF();
}
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63469")]
+ public void ScopedAsParameterName_06_Preview_B()
+ {
+ string source = "(scoped scoped, int i) => { }";
+ UsingExpression(source, TestOptions.RegularPreview);
+
+ N(SyntaxKind.ParenthesizedLambdaExpression);
+ {
+ N(SyntaxKind.ParameterList);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.Parameter);
+ {
+ N(SyntaxKind.ScopedKeyword);
+ N(SyntaxKind.IdentifierToken, "scoped");
+ }
+ N(SyntaxKind.CommaToken);
+ N(SyntaxKind.Parameter);
+ {
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.IntKeyword);
+ }
+ N(SyntaxKind.IdentifierToken, "i");
+ }
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.EqualsGreaterThanToken);
+ N(SyntaxKind.Block);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ EOF();
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63469")]
+ public void ScopedAsParameterName_06_Preview_C()
+ {
+ string source = "(scoped scoped = default) => { }";
+ UsingExpression(source, TestOptions.RegularPreview);
+
+ N(SyntaxKind.ParenthesizedLambdaExpression);
+ {
+ N(SyntaxKind.ParameterList);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.Parameter);
+ {
+ N(SyntaxKind.ScopedKeyword);
+ N(SyntaxKind.IdentifierToken, "scoped");
+ N(SyntaxKind.EqualsValueClause);
+ {
+ N(SyntaxKind.EqualsToken);
+ N(SyntaxKind.DefaultLiteralExpression);
+ {
+ N(SyntaxKind.DefaultKeyword);
+ }
+ }
+ }
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.EqualsGreaterThanToken);
+ N(SyntaxKind.Block);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ EOF();
+ }
+
[Fact]
public void MissingParameterName_01()
{
@@ -6893,5 +7045,168 @@ public void TestParenthesizedLambdaRecovery3()
}
EOF();
}
+
+ [Theory]
+ [InlineData(LanguageVersion.CSharp13)]
+ [InlineData(LanguageVersion.CSharp14)]
+ public void TestTripleScoped_LocalFunction(LanguageVersion version)
+ {
+ UsingTree("""
+ void Goo(scoped scoped scoped) { }
+ """, TestOptions.Regular.WithLanguageVersion(version));
+
+ N(SyntaxKind.CompilationUnit);
+ {
+ N(SyntaxKind.GlobalStatement);
+ {
+ N(SyntaxKind.LocalFunctionStatement);
+ {
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.VoidKeyword);
+ }
+ N(SyntaxKind.IdentifierToken, "Goo");
+ N(SyntaxKind.ParameterList);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.Parameter);
+ {
+ N(SyntaxKind.ScopedKeyword);
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "scoped");
+ }
+ N(SyntaxKind.IdentifierToken, "scoped");
+ }
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.Block);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ N(SyntaxKind.EndOfFileToken);
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void TestTripleScoped_Lambda_CSharp13()
+ {
+ // In c# 13 this is one scoped modifier on the 'scoped' type on the 'scoped' identifier.
+ UsingTree("""
+ var v = (scoped scoped scoped) => { };
+ """, TestOptions.Regular13);
+
+ N(SyntaxKind.CompilationUnit);
+ {
+ N(SyntaxKind.GlobalStatement);
+ {
+ N(SyntaxKind.LocalDeclarationStatement);
+ {
+ N(SyntaxKind.VariableDeclaration);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "var");
+ }
+ N(SyntaxKind.VariableDeclarator);
+ {
+ N(SyntaxKind.IdentifierToken, "v");
+ N(SyntaxKind.EqualsValueClause);
+ {
+ N(SyntaxKind.EqualsToken);
+ N(SyntaxKind.ParenthesizedLambdaExpression);
+ {
+ N(SyntaxKind.ParameterList);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.Parameter);
+ {
+ N(SyntaxKind.ScopedKeyword);
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "scoped");
+ }
+ N(SyntaxKind.IdentifierToken, "scoped");
+ }
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.EqualsGreaterThanToken);
+ N(SyntaxKind.Block);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ }
+ }
+ N(SyntaxKind.SemicolonToken);
+ }
+ }
+ N(SyntaxKind.EndOfFileToken);
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void TestTripleScoped_Lambda_CSharp14()
+ {
+ // In c# 14 this is two scoped modifiers on the 'scoped' identifier.
+ UsingTree("""
+ var v = (scoped scoped scoped) => { };
+ """, TestOptions.Regular14);
+
+ N(SyntaxKind.CompilationUnit);
+ {
+ N(SyntaxKind.GlobalStatement);
+ {
+ N(SyntaxKind.LocalDeclarationStatement);
+ {
+ N(SyntaxKind.VariableDeclaration);
+ {
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "var");
+ }
+ N(SyntaxKind.VariableDeclarator);
+ {
+ N(SyntaxKind.IdentifierToken, "v");
+ N(SyntaxKind.EqualsValueClause);
+ {
+ N(SyntaxKind.EqualsToken);
+ N(SyntaxKind.ParenthesizedLambdaExpression);
+ {
+ N(SyntaxKind.ParameterList);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.Parameter);
+ {
+ N(SyntaxKind.ScopedKeyword);
+ N(SyntaxKind.ScopedKeyword);
+ N(SyntaxKind.IdentifierToken, "scoped");
+ }
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.EqualsGreaterThanToken);
+ N(SyntaxKind.Block);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ }
+ }
+ }
+ N(SyntaxKind.SemicolonToken);
+ }
+ }
+ N(SyntaxKind.EndOfFileToken);
+ }
+ EOF();
+ }
}
}
diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs
index 6979c47d06efe..075291bf0a1f8 100644
--- a/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs
+++ b/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs
@@ -4,11 +4,12 @@
#nullable disable
-using Xunit;
+using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
+using Xunit;
using Xunit.Abstractions;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Parsing
@@ -931,25 +932,30 @@ void verifyNodes()
public void RefReadonlyWithScoped_02()
{
var source = "void M(ref scoped readonly int p);";
- var expectedDiagnostics = new[]
- {
- // (1,19): error CS1001: Identifier expected
- // void M(ref scoped readonly int p);
- Diagnostic(ErrorCode.ERR_IdentifierExpected, "readonly").WithLocation(1, 19),
- // (1,19): error CS1003: Syntax error, ',' expected
- // void M(ref scoped readonly int p);
- Diagnostic(ErrorCode.ERR_SyntaxError, "readonly").WithArguments(",").WithLocation(1, 19)
- };
- UsingDeclaration(source, TestOptions.Regular11, expectedDiagnostics);
+ UsingDeclaration(source, TestOptions.Regular11);
verifyNodes();
- UsingDeclaration(source, TestOptions.Regular12, expectedDiagnostics);
+ UsingDeclaration(source, TestOptions.Regular12);
verifyNodes();
- UsingDeclaration(source, TestOptions.RegularPreview, expectedDiagnostics);
+ UsingDeclaration(source, TestOptions.RegularPreview);
verifyNodes();
+ CreateCompilation(source).VerifyDiagnostics(
+ // (1,6): error CS8112: Local function 'M(scoped ref int)' must declare a body because it is not marked 'static extern'.
+ // void M(ref scoped readonly int p);
+ Diagnostic(ErrorCode.ERR_LocalFunctionMissingBody, "M").WithArguments("M(scoped ref int)").WithLocation(1, 6),
+ // (1,6): warning CS8321: The local function 'M' is declared but never used
+ // void M(ref scoped readonly int p);
+ Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "M").WithArguments("M").WithLocation(1, 6),
+ // (1,12): error CS9347: The 'scoped' modifier cannot come after an 'in', 'out', 'ref' or 'readonly' modifier.
+ // void M(ref scoped readonly int p);
+ Diagnostic(ErrorCode.ERR_ScopedAfterInOutRefReadonly, "scoped").WithLocation(1, 12),
+ // (1,19): error CS9190: 'readonly' modifier must be specified after 'ref'.
+ // void M(ref scoped readonly int p);
+ Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(1, 19));
+
void verifyNodes()
{
N(SyntaxKind.MethodDeclaration);
@@ -965,15 +971,7 @@ void verifyNodes()
N(SyntaxKind.Parameter);
{
N(SyntaxKind.RefKeyword);
- N(SyntaxKind.IdentifierName);
- {
- N(SyntaxKind.IdentifierToken, "scoped");
- }
- M(SyntaxKind.IdentifierToken);
- }
- M(SyntaxKind.CommaToken);
- N(SyntaxKind.Parameter);
- {
+ N(SyntaxKind.ScopedKeyword);
N(SyntaxKind.ReadOnlyKeyword);
N(SyntaxKind.PredefinedType);
{
@@ -993,25 +991,27 @@ void verifyNodes()
public void RefReadonlyWithScoped_03()
{
var source = "void M(readonly scoped ref int p);";
- var expectedDiagnostics = new[]
- {
- // (1,24): error CS1001: Identifier expected
- // void M(readonly scoped ref int p);
- Diagnostic(ErrorCode.ERR_IdentifierExpected, "ref").WithLocation(1, 24),
- // (1,24): error CS1003: Syntax error, ',' expected
- // void M(readonly scoped ref int p);
- Diagnostic(ErrorCode.ERR_SyntaxError, "ref").WithArguments(",").WithLocation(1, 24)
- };
- UsingDeclaration(source, TestOptions.Regular11, expectedDiagnostics);
+ UsingDeclaration(source, TestOptions.Regular11);
verifyNodes();
- UsingDeclaration(source, TestOptions.Regular12, expectedDiagnostics);
+ UsingDeclaration(source, TestOptions.Regular12);
verifyNodes();
- UsingDeclaration(source, TestOptions.RegularPreview, expectedDiagnostics);
+ UsingDeclaration(source, TestOptions.RegularPreview);
verifyNodes();
+ CreateCompilation(source).VerifyDiagnostics(
+ // (1,6): error CS8112: Local function 'M(scoped ref int)' must declare a body because it is not marked 'static extern'.
+ // void M(readonly scoped ref int p);
+ Diagnostic(ErrorCode.ERR_LocalFunctionMissingBody, "M").WithArguments("M(scoped ref int)").WithLocation(1, 6),
+ // (1,6): warning CS8321: The local function 'M' is declared but never used
+ // void M(readonly scoped ref int p);
+ Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "M").WithArguments("M").WithLocation(1, 6),
+ // (1,8): error CS9190: 'readonly' modifier must be specified after 'ref'.
+ // void M(readonly scoped ref int p);
+ Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(1, 8));
+
void verifyNodes()
{
N(SyntaxKind.MethodDeclaration);
@@ -1027,15 +1027,7 @@ void verifyNodes()
N(SyntaxKind.Parameter);
{
N(SyntaxKind.ReadOnlyKeyword);
- N(SyntaxKind.IdentifierName);
- {
- N(SyntaxKind.IdentifierToken, "scoped");
- }
- M(SyntaxKind.IdentifierToken);
- }
- M(SyntaxKind.CommaToken);
- N(SyntaxKind.Parameter);
- {
+ N(SyntaxKind.ScopedKeyword);
N(SyntaxKind.RefKeyword);
N(SyntaxKind.PredefinedType);
{
@@ -1055,25 +1047,33 @@ void verifyNodes()
public void ReadonlyWithScoped()
{
var source = "void M(scoped readonly int p);";
- var expectedDiagnostics = new[]
- {
- // (1,15): error CS1001: Identifier expected
- // void M(scoped readonly int p);
- Diagnostic(ErrorCode.ERR_IdentifierExpected, "readonly").WithLocation(1, 15),
- // (1,15): error CS1003: Syntax error, ',' expected
- // void M(scoped readonly int p);
- Diagnostic(ErrorCode.ERR_SyntaxError, "readonly").WithArguments(",").WithLocation(1, 15)
- };
- UsingDeclaration(source, TestOptions.Regular11, expectedDiagnostics);
+ UsingDeclaration(source, TestOptions.Regular11);
verifyNodes();
- UsingDeclaration(source, TestOptions.Regular12, expectedDiagnostics);
+ UsingDeclaration(source, TestOptions.Regular12);
verifyNodes();
- UsingDeclaration(source, TestOptions.RegularPreview, expectedDiagnostics);
+ UsingDeclaration(source, TestOptions.RegularPreview);
verifyNodes();
+ CreateCompilation(source).VerifyDiagnostics(
+ // (1,6): error CS8112: Local function 'M(scoped int)' must declare a body because it is not marked 'static extern'.
+ // void M(scoped readonly int p);
+ Diagnostic(ErrorCode.ERR_LocalFunctionMissingBody, "M").WithArguments("M(scoped int)").WithLocation(1, 6),
+ // (1,6): warning CS8321: The local function 'M' is declared but never used
+ // void M(scoped readonly int p);
+ Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "M").WithArguments("M").WithLocation(1, 6),
+ // (1,8): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only.
+ // void M(scoped readonly int p);
+ Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped readonly int p").WithLocation(1, 8),
+ // (1,15): error CS9348: The 'readonly' modifier cannot immediately follow the 'scoped' modifier.
+ // void M(scoped readonly int p);
+ Diagnostic(ErrorCode.ERR_InvalidModifierAfterScoped, "readonly").WithArguments("readonly").WithLocation(1, 15),
+ // (1,15): error CS9190: 'readonly' modifier must be specified after 'ref'.
+ // void M(scoped readonly int p);
+ Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(1, 15));
+
void verifyNodes()
{
N(SyntaxKind.MethodDeclaration);
@@ -1088,15 +1088,7 @@ void verifyNodes()
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
- N(SyntaxKind.IdentifierName);
- {
- N(SyntaxKind.IdentifierToken, "scoped");
- }
- M(SyntaxKind.IdentifierToken);
- }
- M(SyntaxKind.CommaToken);
- N(SyntaxKind.Parameter);
- {
+ N(SyntaxKind.ScopedKeyword);
N(SyntaxKind.ReadOnlyKeyword);
N(SyntaxKind.PredefinedType);
{
@@ -1116,25 +1108,30 @@ void verifyNodes()
public void ReadonlyWithScoped_02()
{
var source = "void M(scoped readonly ref int p);";
- var expectedDiagnostics = new[]
- {
- // (1,15): error CS1001: Identifier expected
- // void M(scoped readonly ref int p);
- Diagnostic(ErrorCode.ERR_IdentifierExpected, "readonly").WithLocation(1, 15),
- // (1,15): error CS1003: Syntax error, ',' expected
- // void M(scoped readonly ref int p);
- Diagnostic(ErrorCode.ERR_SyntaxError, "readonly").WithArguments(",").WithLocation(1, 15)
- };
- UsingDeclaration(source, TestOptions.Regular11, expectedDiagnostics);
+ UsingDeclaration(source, TestOptions.Regular11);
verifyNodes();
- UsingDeclaration(source, TestOptions.Regular12, expectedDiagnostics);
+ UsingDeclaration(source, TestOptions.Regular12);
verifyNodes();
- UsingDeclaration(source, TestOptions.RegularPreview, expectedDiagnostics);
+ UsingDeclaration(source, TestOptions.RegularPreview);
verifyNodes();
+ CreateCompilation(source).VerifyDiagnostics(
+ // (1,6): error CS8112: Local function 'M(scoped ref int)' must declare a body because it is not marked 'static extern'.
+ // void M(scoped readonly ref int p);
+ Diagnostic(ErrorCode.ERR_LocalFunctionMissingBody, "M").WithArguments("M(scoped ref int)").WithLocation(1, 6),
+ // (1,6): warning CS8321: The local function 'M' is declared but never used
+ // void M(scoped readonly ref int p);
+ Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "M").WithArguments("M").WithLocation(1, 6),
+ // (1,15): error CS9348: The 'readonly' modifier cannot immediately follow the 'scoped' modifier.
+ // void M(scoped readonly ref int p);
+ Diagnostic(ErrorCode.ERR_InvalidModifierAfterScoped, "readonly").WithArguments("readonly").WithLocation(1, 15),
+ // (1,15): error CS9190: 'readonly' modifier must be specified after 'ref'.
+ // void M(scoped readonly ref int p);
+ Diagnostic(ErrorCode.ERR_RefReadOnlyWrongOrdering, "readonly").WithLocation(1, 15));
+
void verifyNodes()
{
N(SyntaxKind.MethodDeclaration);
@@ -1149,15 +1146,7 @@ void verifyNodes()
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.Parameter);
{
- N(SyntaxKind.IdentifierName);
- {
- N(SyntaxKind.IdentifierToken, "scoped");
- }
- M(SyntaxKind.IdentifierToken);
- }
- M(SyntaxKind.CommaToken);
- N(SyntaxKind.Parameter);
- {
+ N(SyntaxKind.ScopedKeyword);
N(SyntaxKind.ReadOnlyKeyword);
N(SyntaxKind.RefKeyword);
N(SyntaxKind.PredefinedType);
@@ -1370,6 +1359,262 @@ public void ArgumentModifier_RefReadonly(
EOF();
}
+ [Fact]
+ public void ScopedThis()
+ {
+ var source = """
+ ref struct S { }
+ static class C
+ {
+ public static void M(scoped this S x)
+ {
+ }
+ }
+ """;
+ UsingTree(source);
+ CreateCompilation(source).VerifyDiagnostics(
+ // (4,33): error CS9348: The 'this' modifier cannot immediately follow the 'scoped' modifier.
+ // public static void M(scoped this S x)
+ Diagnostic(ErrorCode.ERR_InvalidModifierAfterScoped, "this").WithArguments("this").WithLocation(4, 33));
+
+ N(SyntaxKind.CompilationUnit);
+ {
+ N(SyntaxKind.StructDeclaration);
+ {
+ N(SyntaxKind.RefKeyword);
+ N(SyntaxKind.StructKeyword);
+ N(SyntaxKind.IdentifierToken, "S");
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ N(SyntaxKind.ClassDeclaration);
+ {
+ N(SyntaxKind.StaticKeyword);
+ N(SyntaxKind.ClassKeyword);
+ N(SyntaxKind.IdentifierToken, "C");
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.MethodDeclaration);
+ {
+ N(SyntaxKind.PublicKeyword);
+ N(SyntaxKind.StaticKeyword);
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.VoidKeyword);
+ }
+ N(SyntaxKind.IdentifierToken, "M");
+ N(SyntaxKind.ParameterList);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.Parameter);
+ {
+ N(SyntaxKind.ScopedKeyword);
+ N(SyntaxKind.ThisKeyword);
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "S");
+ }
+ N(SyntaxKind.IdentifierToken, "x");
+ }
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.Block);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ N(SyntaxKind.EndOfFileToken);
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void ThisScoped()
+ {
+ var source = """
+ ref struct S { }
+
+ static class C
+ {
+ public static void M(this scoped S x)
+ {
+ }
+ }
+ """;
+ UsingTree(source);
+ CreateCompilation(source).VerifyDiagnostics();
+
+ N(SyntaxKind.CompilationUnit);
+ {
+ N(SyntaxKind.StructDeclaration);
+ {
+ N(SyntaxKind.RefKeyword);
+ N(SyntaxKind.StructKeyword);
+ N(SyntaxKind.IdentifierToken, "S");
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ N(SyntaxKind.ClassDeclaration);
+ {
+ N(SyntaxKind.StaticKeyword);
+ N(SyntaxKind.ClassKeyword);
+ N(SyntaxKind.IdentifierToken, "C");
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.MethodDeclaration);
+ {
+ N(SyntaxKind.PublicKeyword);
+ N(SyntaxKind.StaticKeyword);
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.VoidKeyword);
+ }
+ N(SyntaxKind.IdentifierToken, "M");
+ N(SyntaxKind.ParameterList);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.Parameter);
+ {
+ N(SyntaxKind.ThisKeyword);
+ N(SyntaxKind.ScopedKeyword);
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "S");
+ }
+ N(SyntaxKind.IdentifierToken, "x");
+ }
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.Block);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ N(SyntaxKind.EndOfFileToken);
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void ScopedParams()
+ {
+ var source = """
+ static class C
+ {
+ public static void M(scoped params S x)
+ {
+ }
+ }
+ """;
+ UsingTree(source);
+
+ N(SyntaxKind.CompilationUnit);
+ {
+ N(SyntaxKind.ClassDeclaration);
+ {
+ N(SyntaxKind.StaticKeyword);
+ N(SyntaxKind.ClassKeyword);
+ N(SyntaxKind.IdentifierToken, "C");
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.MethodDeclaration);
+ {
+ N(SyntaxKind.PublicKeyword);
+ N(SyntaxKind.StaticKeyword);
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.VoidKeyword);
+ }
+ N(SyntaxKind.IdentifierToken, "M");
+ N(SyntaxKind.ParameterList);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.Parameter);
+ {
+ N(SyntaxKind.ScopedKeyword);
+ N(SyntaxKind.ParamsKeyword);
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "S");
+ }
+ N(SyntaxKind.IdentifierToken, "x");
+ }
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.Block);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ N(SyntaxKind.EndOfFileToken);
+ }
+ EOF();
+ }
+
+ [Fact]
+ public void ParamsScoped()
+ {
+ var source = """
+ static class C
+ {
+ public static void M(params scoped S x)
+ {
+ }
+ }
+ """;
+ UsingTree(source);
+
+ N(SyntaxKind.CompilationUnit);
+ {
+ N(SyntaxKind.ClassDeclaration);
+ {
+ N(SyntaxKind.StaticKeyword);
+ N(SyntaxKind.ClassKeyword);
+ N(SyntaxKind.IdentifierToken, "C");
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.MethodDeclaration);
+ {
+ N(SyntaxKind.PublicKeyword);
+ N(SyntaxKind.StaticKeyword);
+ N(SyntaxKind.PredefinedType);
+ {
+ N(SyntaxKind.VoidKeyword);
+ }
+ N(SyntaxKind.IdentifierToken, "M");
+ N(SyntaxKind.ParameterList);
+ {
+ N(SyntaxKind.OpenParenToken);
+ N(SyntaxKind.Parameter);
+ {
+ N(SyntaxKind.ParamsKeyword);
+ N(SyntaxKind.ScopedKeyword);
+ N(SyntaxKind.IdentifierName);
+ {
+ N(SyntaxKind.IdentifierToken, "S");
+ }
+ N(SyntaxKind.IdentifierToken, "x");
+ }
+ N(SyntaxKind.CloseParenToken);
+ }
+ N(SyntaxKind.Block);
+ {
+ N(SyntaxKind.OpenBraceToken);
+ N(SyntaxKind.CloseBraceToken);
+ }
+ }
+ N(SyntaxKind.CloseBraceToken);
+ }
+ N(SyntaxKind.EndOfFileToken);
+ }
+ EOF();
+ }
+
[Theory, CombinatorialData]
public void ArgumentModifier_ReadonlyRef(
[CombinatorialValues(LanguageVersion.CSharp11, LanguageVersion.CSharp12, LanguageVersion.Preview)] LanguageVersion languageVersion)
diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/TopLevelStatementsParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/TopLevelStatementsParsingTests.cs
index 24430e3e15adb..aedda8d3b2ba6 100644
--- a/src/Compilers/CSharp/Test/Syntax/Parsing/TopLevelStatementsParsingTests.cs
+++ b/src/Compilers/CSharp/Test/Syntax/Parsing/TopLevelStatementsParsingTests.cs
@@ -3066,10 +3066,9 @@ scoped readonly ref struct C { }
// (3,12): error CS1031: Type expected
// scoped ref struct B { }
Diagnostic(ErrorCode.ERR_TypeExpected, "struct").WithLocation(3, 12),
- // (4,8): error CS1585: Member modifier 'readonly' must precede the member type and name
+ // (4,1): error CS0116: A namespace cannot directly contain members such as fields, methods or statements
// scoped readonly ref struct C { }
- Diagnostic(ErrorCode.ERR_BadModifierLocation, "readonly").WithArguments("readonly").WithLocation(4, 8)
- );
+ Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "scoped").WithLocation(4, 1));
N(SyntaxKind.CompilationUnit);
{
@@ -3119,10 +3118,7 @@ scoped readonly ref struct C { }
}
N(SyntaxKind.IncompleteMember);
{
- N(SyntaxKind.IdentifierName);
- {
- N(SyntaxKind.IdentifierToken, "scoped");
- }
+ N(SyntaxKind.ScopedKeyword);
}
N(SyntaxKind.StructDeclaration);
{