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(); + void local() { } // 2 + } + + void M2() + { + local(); + void local<@scoped>() { } + } +} + +class D2 +{ + void M() { } // 3 + void M2<@scoped>() { } +} +"""; + var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10); + comp.VerifyDiagnostics( + // (1,9): warning CS8981: The type name 'scoped' only contains lower-cased ascii characters. Such names may become reserved for the language. + // class C { } // 1 + Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "scoped").WithArguments("scoped").WithLocation(1, 9), + // (9,20): warning CS8981: The type name 'scoped' only contains lower-cased ascii characters. Such names may become reserved for the language. + // void local() { } // 2 + Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "scoped").WithArguments("scoped").WithLocation(9, 20), + // (21,12): warning CS8981: The type name 'scoped' only contains lower-cased ascii characters. Such names may become reserved for the language. + // void M() { } // 3 + Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "scoped").WithArguments("scoped").WithLocation(21, 12) + ); + + comp = CreateCompilation(source, parseOptions: TestOptions.Regular11); + comp.VerifyDiagnostics( + // (1,9): error CS9062: Types and aliases cannot be named 'scoped'. + // class C { } // 1 + Diagnostic(ErrorCode.ERR_ScopedTypeNameDisallowed, "scoped").WithLocation(1, 9), + // (9,20): error CS9062: Types and aliases cannot be named 'scoped'. + // void local() { } // 2 + Diagnostic(ErrorCode.ERR_ScopedTypeNameDisallowed, "scoped").WithLocation(9, 20), + // (21,12): error CS9062: Types and aliases cannot be named 'scoped'. + // void M() { } // 3 + Diagnostic(ErrorCode.ERR_ScopedTypeNameDisallowed, "scoped").WithLocation(21, 12) + ); + } + + [Fact, WorkItem(62931, "https://github.com/dotnet/roslyn/issues/62931")] + public void ScopedReserved_Alias() + { + var source = """ +using scoped = System.Int32; +"""; + var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10); + comp.VerifyDiagnostics( + // (1,1): hidden CS8019: Unnecessary using directive. + // using scoped = System.Int32; + Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using scoped = System.Int32;").WithLocation(1, 1), + // (1,7): warning CS8981: The type name 'scoped' only contains lower-cased ascii characters. Such names may become reserved for the language. + // using scoped = System.Int32; + Diagnostic(ErrorCode.WRN_LowerCaseTypeName, "scoped").WithArguments("scoped").WithLocation(1, 7) + ); + + comp = CreateCompilation(source, parseOptions: TestOptions.Regular11); + comp.VerifyDiagnostics( + // (1,1): hidden CS8019: Unnecessary using directive. + // using scoped = System.Int32; + Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using scoped = System.Int32;").WithLocation(1, 1), + // (1,7): error CS9062: Types and aliases cannot be named 'scoped'. + // using scoped = System.Int32; + Diagnostic(ErrorCode.ERR_ScopedTypeNameDisallowed, "scoped").WithLocation(1, 7) + ); + } + + [Fact, WorkItem(62931, "https://github.com/dotnet/roslyn/issues/62931")] + public void ScopedReserved_Alias_Escaped() + { + var source = """ +using @scoped = System.Int32; +"""; + var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10); + comp.VerifyDiagnostics( + // (1,1): hidden CS8019: Unnecessary using directive. + // using @scoped = System.Int32; + Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using @scoped = System.Int32;").WithLocation(1, 1) + ); + + comp = CreateCompilation(source, parseOptions: TestOptions.Regular11); + comp.VerifyDiagnostics( + // (1,1): hidden CS8019: Unnecessary using directive. + // using @scoped = System.Int32; + Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using @scoped = System.Int32;").WithLocation(1, 1) + ); + } } } diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationScopeParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationScopeParsingTests.cs index 39582c4dd970f..a392cb0767971 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationScopeParsingTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationScopeParsingTests.cs @@ -1879,8 +1879,6 @@ public void TypeNamedScoped(LanguageVersion langVersion) string source = @" class scoped { } "; - // Missing error - // Tracked by https://github.com/dotnet/roslyn/issues/62931 UsingTree(source, TestOptions.Regular.WithLanguageVersion(langVersion)); N(SyntaxKind.CompilationUnit);