diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index 982e92bcda0a8..f2fbdd8911381 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -7202,4 +7202,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
Unexpected contextual keyword 'scoped'. Did you mean 'scoped ref' or '@scoped'?
+
+ Types and aliases cannot be named 'scoped'.
+
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
index 5018dd8737276..05b7a32e2c1ee 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@@ -2110,6 +2110,7 @@ internal enum ErrorCode
ERR_RefFieldInNonRefStruct = 9059,
ERR_CannotMatchOnINumberBase = 9060,
ERR_MisplacedScoped = 9061,
+ ERR_ScopedTypeNameDisallowed = 9062,
#endregion
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
index 0a65568e6e465..a338a2240b4c6 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
@@ -2211,6 +2211,7 @@ internal static bool IsBuildOnlyDiagnostic(ErrorCode code)
case ErrorCode.WRN_AnalyzerReferencesNewerCompiler:
case ErrorCode.ERR_CannotMatchOnINumberBase:
case ErrorCode.ERR_MisplacedScoped:
+ case ErrorCode.ERR_ScopedTypeNameDisallowed:
return false;
default:
// NOTE: All error codes must be explicitly handled in this switch statement
diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs
index 17519bd84c86d..b254a359f5e65 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs
@@ -478,7 +478,8 @@ internal static void ReportReservedTypeName(string? name, CSharpCompilation comp
if (reportIfContextual(SyntaxKind.RecordKeyword, MessageID.IDS_FeatureRecords, ErrorCode.WRN_RecordNamedDisallowed)
|| reportIfContextual(SyntaxKind.RequiredKeyword, MessageID.IDS_FeatureRequiredMembers, ErrorCode.ERR_RequiredNameDisallowed)
- || reportIfContextual(SyntaxKind.FileKeyword, MessageID.IDS_FeatureFileTypes, ErrorCode.ERR_FileTypeNameDisallowed))
+ || reportIfContextual(SyntaxKind.FileKeyword, MessageID.IDS_FeatureFileTypes, ErrorCode.ERR_FileTypeNameDisallowed)
+ || reportIfContextual(SyntaxKind.ScopedKeyword, MessageID.IDS_FeatureRefFields, ErrorCode.ERR_ScopedTypeNameDisallowed))
{
return;
}
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
index db5ec1f37a833..b009aa8742a86 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
@@ -1387,6 +1387,11 @@
Modifikátor scoped se dá použít jen pro hodnoty refs a ref struct.
+
+ Types and aliases cannot be named 'scoped'.
+ Types and aliases cannot be named 'scoped'.
+
+ Required members are not allowed on the top level of a script or submission.Povinní členové nejsou povoleni na nejvyšší úrovni skriptu nebo odeslání.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
index 86c688aca56f6..0b57395eb50c7 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
@@ -1387,6 +1387,11 @@
Der Modifikator ‚Scoped‘ kann nur für Refs und Ref-Strukturwerte verwendet werden.
+
+ Types and aliases cannot be named 'scoped'.
+ Types and aliases cannot be named 'scoped'.
+
+ Required members are not allowed on the top level of a script or submission.Erforderliche Mitglieder sind auf der obersten Ebene eines Skripts oder einer Übermittlung nicht zulässig.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
index 013eeded6c54e..fa09c09c3822a 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
@@ -1387,6 +1387,11 @@
El modificador 'scoped' solo se puede usar para referencias y valores de estructura de referencia.
+
+ Types and aliases cannot be named 'scoped'.
+ Types and aliases cannot be named 'scoped'.
+
+ Required members are not allowed on the top level of a script or submission.No se permiten miembros necesarios en el nivel superior de un script o envío.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
index 47ce6c5466f89..1abd33a14f021 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
@@ -1387,6 +1387,11 @@
Le modificateur 'scoped' ne peut être utilisé que pour les valeurs refs et ref struct.
+
+ Types and aliases cannot be named 'scoped'.
+ Types and aliases cannot be named 'scoped'.
+
+ Required members are not allowed on the top level of a script or submission.Les membres requis ne sont pas autorisés au niveau supérieur d’un script ou d’une soumission.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
index 3bbb9a386227c..367e9626e8393 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
@@ -1387,6 +1387,11 @@
Il modificatore 'scoped' può essere usato solo per i riferimenti e i valori ref struct.
+
+ Types and aliases cannot be named 'scoped'.
+ Types and aliases cannot be named 'scoped'.
+
+ Required members are not allowed on the top level of a script or submission.I membri obbligatori non sono consentiti al primo livello di uno script o di un invio.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
index 5d1a6b45bae09..1128c3ca900b7 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
@@ -1387,6 +1387,11 @@
'scoped' 修飾子は refs および ref 構造体の値にのみ使用できます。
+
+ Types and aliases cannot be named 'scoped'.
+ Types and aliases cannot be named 'scoped'.
+
+ Required members are not allowed on the top level of a script or submission.必要なメンバーは、スクリプトまたは送信の最上位レベルでは許可されていません。
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
index 3f9e010996fc4..6792a71260d8c 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
@@ -1387,6 +1387,11 @@
'scoped' 한정자는 ref 및 ref 구조체 값에만 사용할 수 있습니다.
+
+ Types and aliases cannot be named 'scoped'.
+ Types and aliases cannot be named 'scoped'.
+
+ Required members are not allowed on the top level of a script or submission.필수 멤버는 스크립트 또는 제출의 최상위 수준에서 허용되지 않습니다.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
index 085720a705d24..cbd9a7e9dda3c 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
@@ -1387,6 +1387,11 @@
Modyfikator „scoped" może być używany tylko w przypadku odwołań i wartości struktury referencyjnej.
+
+ Types and aliases cannot be named 'scoped'.
+ Types and aliases cannot be named 'scoped'.
+
+ Required members are not allowed on the top level of a script or submission.Wymagane składowe są niedozwolone na najwyższym poziomie skryptu lub żądania przesłania.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
index 8f94e134deb01..e97227e174e19 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
@@ -1387,6 +1387,11 @@
O modificador 'scoped' só pode ser usado para valores de struct refs e ref.
+
+ Types and aliases cannot be named 'scoped'.
+ Types and aliases cannot be named 'scoped'.
+
+ Required members are not allowed on the top level of a script or submission.Os membros necessários não são permitidos no nível superior de um script ou envio.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
index 9253b8f0f794e..f64cfb57740bf 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
@@ -1387,6 +1387,11 @@
Модификатор "scoped" можно использовать только для ref и для значений ref struct.
+
+ Types and aliases cannot be named 'scoped'.
+ Types and aliases cannot be named 'scoped'.
+
+ Required members are not allowed on the top level of a script or submission.Обязательные члены не разрешены на верхнем уровне сценария или отправки.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
index 56b3d09e883d5..832a9b9a13c4e 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
@@ -1387,6 +1387,11 @@
'scoped' değiştiricisi yalnızca başvurular ve başvuru yapı değerleri için kullanılabilir.
+
+ Types and aliases cannot be named 'scoped'.
+ Types and aliases cannot be named 'scoped'.
+
+ Required members are not allowed on the top level of a script or submission.Bir betiğin veya gönderimin en üst düzeyinde gerekli üyelere izin verilmez.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
index 459b1872afc70..7b2aca9973b9c 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
@@ -1387,6 +1387,11 @@
"scoped" 修饰符只能用于 refs 和 ref 结构值。
+
+ Types and aliases cannot be named 'scoped'.
+ Types and aliases cannot be named 'scoped'.
+
+ Required members are not allowed on the top level of a script or submission.所需成员不在脚本或提交的顶层受允许。
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
index 67b5e20a9ac16..2c32044926414 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
@@ -1387,6 +1387,11 @@
'scoped' 修飾元只能用於 refs 和 ref 結構值。
+
+ Types and aliases cannot be named 'scoped'.
+ Types and aliases cannot be named 'scoped'.
+
+ Required members are not allowed on the top level of a script or submission.指令碼或提交的頂層不允許必要的成員。
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs
index be630e7afe859..9d945efed5318 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs
@@ -6814,7 +6814,7 @@ static void Main()
public void ParameterScope_09()
{
var source =
-@"ref struct scoped { }
+@"ref struct @scoped { }
class Program
{
static void F0(scoped s) { }
@@ -6831,9 +6831,6 @@ static void F7(scoped in scoped s) { }
}";
var comp = CreateCompilation(source);
comp.VerifyEmitDiagnostics(
- // (1,12): warning CS8981: The type name 'scoped' only contains lower-cased ascii characters. Such names may become reserved for the language.
- // ref struct scoped { }
- Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "scoped").WithArguments("scoped").WithLocation(1, 12),
// (7,24): error CS8339: The parameter modifier 'scoped' cannot follow 'ref'
// static void F3(ref scoped scoped s) { }
Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "scoped").WithArguments("scoped", "ref").WithLocation(7, 24),
@@ -7434,7 +7431,7 @@ public void LocalScope_04()
scoped scoped s4 = default; // 2
scoped ref scoped s5 = ref s1; // 3
scoped ref @scoped s6 = ref s1; // 4
-ref struct scoped { } // 5
+ref struct @scoped { } // 5
";
var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
comp.VerifyEmitDiagnostics(
@@ -7458,10 +7455,7 @@ ref struct scoped { } // 5
Diagnostic(ErrorCode.ERR_InvalidExprTerm, "=").WithArguments("=").WithLocation(5, 22),
// (6,1): error CS8936: Feature 'ref fields' is not available in C# 10.0. Please use language version 11.0 or greater.
// scoped ref @scoped s6 = ref s1; // 4
- Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(6, 1),
- // (7,12): warning CS8981: The type name 'scoped' only contains lower-cased ascii characters. Such names may become reserved for the language.
- // ref struct scoped { } // 5
- Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "scoped").WithArguments("scoped").WithLocation(7, 12));
+ Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "scoped").WithArguments("ref fields", "11.0").WithLocation(6, 1));
verify(comp);
comp = CreateCompilation(source);
@@ -7480,10 +7474,7 @@ ref struct scoped { } // 5
Diagnostic(ErrorCode.ERR_MisplacedScoped, "scoped").WithLocation(5, 12),
// (5,22): error CS1525: Invalid expression term '='
// scoped ref scoped s5 = ref s1; // 3
- Diagnostic(ErrorCode.ERR_InvalidExprTerm, "=").WithArguments("=").WithLocation(5, 22),
- // (7,12): warning CS8981: The type name 'scoped' only contains lower-cased ascii characters. Such names may become reserved for the language.
- // ref struct scoped { } // 5
- Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "scoped").WithArguments("scoped").WithLocation(7, 12));
+ Diagnostic(ErrorCode.ERR_InvalidExprTerm, "=").WithArguments("=").WithLocation(5, 22));
verify(comp);
static void verify(CSharpCompilation comp)
@@ -12509,5 +12500,147 @@ void M()
Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "scoped").WithArguments("scoped", "ref").WithLocation(6, 23)
);
}
+
+ [Theory, WorkItem(62931, "https://github.com/dotnet/roslyn/issues/62931")]
+ [InlineData("class")]
+ [InlineData("struct")]
+ [InlineData("interface")]
+ [InlineData("enum")]
+ [InlineData("record")]
+ public void ScopedReserved_Type(string typeKind)
+ {
+ var source = $$"""
+{{typeKind}} scoped { }
+""";
+ var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
+ comp.VerifyDiagnostics(
+ // (1,8): warning CS8981: The type name 'scoped' only contains lower-cased ascii characters. Such names may become reserved for the language.
+ // struct scoped { }
+ Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "scoped").WithArguments("scoped")
+ );
+
+ comp = CreateCompilation(source, parseOptions: TestOptions.Regular11);
+ comp.VerifyDiagnostics(
+ // (1,8): error CS9062: Types and aliases cannot be named 'scoped'.
+ // struct scoped { }
+ Diagnostic(ErrorCode.ERR_ScopedTypeNameDisallowed, "scoped")
+ );
+ }
+
+ [Fact, WorkItem(62931, "https://github.com/dotnet/roslyn/issues/62931")]
+ public void ScopedReserved_Type_Escaped()
+ {
+ var source = """
+class @scoped { }
+""";
+ var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
+ comp.VerifyDiagnostics();
+
+ comp = CreateCompilation(source, parseOptions: TestOptions.Regular11);
+ comp.VerifyDiagnostics();
+ }
+
+ [Fact, WorkItem(62931, "https://github.com/dotnet/roslyn/issues/62931")]
+ public void ScopedReserved_TypeParameter()
+ {
+ var source = """
+class C { } // 1
+class C2<@scoped> { }
+
+class D
+{
+ void M()
+ {
+ local