diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index c422390669276..554c92a3cd9e4 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -6416,6 +6416,12 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
Members named 'Clone' are disallowed in records.
+
+ A type should not be named 'record'.
+
+
+ A type should not be named 'record'.
+
'{0}' must allow overriding because the containing record is not sealed.
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
index 33f59d087a838..93997a8972abb 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@@ -1853,7 +1853,7 @@ internal enum ErrorCode
ERR_InvalidWithReceiverType = 8857,
ERR_NoSingleCloneMethod = 8858,
ERR_CloneDisallowedInRecord = 8859,
- // available = 8860,
+ WRN_RecordNamedDisallowed = 8860,
ERR_UnexpectedArgumentList = 8861,
ERR_UnexpectedOrMissingConstructorInitializerInRecord = 8862,
ERR_MultipleRecordParameterLists = 8863,
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
index ab96b25305990..84c970400eecd 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
@@ -474,6 +474,7 @@ internal static int GetWarningLevel(ErrorCode code)
case ErrorCode.WRN_IsPatternAlways:
case ErrorCode.WRN_SwitchExpressionNotExhaustiveWithWhen:
case ErrorCode.WRN_SwitchExpressionNotExhaustiveForNullWithWhen:
+ case ErrorCode.WRN_RecordNamedDisallowed:
return 1;
default:
return 0;
diff --git a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs
index 88a36b09f9c77..0f237098cb89a 100644
--- a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs
+++ b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs
@@ -249,6 +249,7 @@ public static bool IsWarning(ErrorCode code)
case ErrorCode.WRN_SwitchExpressionNotExhaustiveWithWhen:
case ErrorCode.WRN_SwitchExpressionNotExhaustiveForNullWithWhen:
case ErrorCode.WRN_PrecedenceInversion:
+ case ErrorCode.WRN_RecordNamedDisallowed:
case ErrorCode.WRN_UnassignedThisAutoProperty:
case ErrorCode.WRN_UnassignedThis:
case ErrorCode.WRN_ParamUnassigned:
diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs
index b473eb569646f..da0f79fae5e2c 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs
@@ -285,7 +285,6 @@ private DeclarationModifiers MakeModifiers(TypeKind typeKind, DiagnosticBag diag
var mods = MakeAndCheckTypeModifiers(
defaultAccess,
allowedModifiers,
- this,
diagnostics,
out modifierErrors);
@@ -324,7 +323,6 @@ private DeclarationModifiers MakeModifiers(TypeKind typeKind, DiagnosticBag diag
private DeclarationModifiers MakeAndCheckTypeModifiers(
DeclarationModifiers defaultAccess,
DeclarationModifiers allowedModifiers,
- SourceMemberContainerTypeSymbol self,
DiagnosticBag diagnostics,
out bool modifierErrors)
{
@@ -356,7 +354,7 @@ private DeclarationModifiers MakeAndCheckTypeModifiers(
var info = ModifierUtils.CheckAccessibility(mods, this, isExplicitInterfaceImplementation: false);
if (info != null)
{
- diagnostics.Add(info, self.Locations[0]);
+ diagnostics.Add(info, this.Locations[0]);
modifierErrors = true;
}
}
@@ -383,12 +381,12 @@ private DeclarationModifiers MakeAndCheckTypeModifiers(
if ((result & DeclarationModifiers.Partial) == 0)
{
// duplicate definitions
- switch (self.ContainingSymbol.Kind)
+ switch (this.ContainingSymbol.Kind)
{
case SymbolKind.Namespace:
for (var i = 1; i < partCount; i++)
{
- diagnostics.Add(ErrorCode.ERR_DuplicateNameInNS, declaration.Declarations[i].NameLocation, self.Name, self.ContainingSymbol);
+ diagnostics.Add(ErrorCode.ERR_DuplicateNameInNS, declaration.Declarations[i].NameLocation, this.Name, this.ContainingSymbol);
modifierErrors = true;
}
break;
@@ -397,7 +395,7 @@ private DeclarationModifiers MakeAndCheckTypeModifiers(
for (var i = 1; i < partCount; i++)
{
if (ContainingType!.Locations.Length == 1 || ContainingType.IsPartial())
- diagnostics.Add(ErrorCode.ERR_DuplicateNameInClass, declaration.Declarations[i].NameLocation, self.ContainingSymbol, self.Name);
+ diagnostics.Add(ErrorCode.ERR_DuplicateNameInClass, declaration.Declarations[i].NameLocation, this.ContainingSymbol, this.Name);
modifierErrors = true;
}
break;
@@ -411,13 +409,18 @@ private DeclarationModifiers MakeAndCheckTypeModifiers(
var mods = singleDeclaration.Modifiers;
if ((mods & DeclarationModifiers.Partial) == 0)
{
- diagnostics.Add(ErrorCode.ERR_MissingPartial, singleDeclaration.NameLocation, self.Name);
+ diagnostics.Add(ErrorCode.ERR_MissingPartial, singleDeclaration.NameLocation, this.Name);
modifierErrors = true;
}
}
}
}
+ if (this.Name == "record")
+ {
+ diagnostics.Add(ErrorCode.WRN_RecordNamedDisallowed, declaration.Declarations[0].NameLocation, this.Name);
+ }
+
return result;
}
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
index ad55c9b5fdc3b..fe5c2a3f60ac9 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
@@ -2504,6 +2504,16 @@
Type does not implement the collection pattern; member is is not a public instance or extension method.
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+ A method marked [DoesNotReturn] should not return.Metoda označená jako [DoesNotReturn] by neměla vracet hodnotu
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
index 8e35042daf2f0..4f3f4e7f2024a 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
@@ -2504,6 +2504,16 @@
Type does not implement the collection pattern; member is is not a public instance or extension method.
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+ A method marked [DoesNotReturn] should not return.Eine mit [DoesNotReturn] gekennzeichnete Methode darf nicht zurückgegeben werden.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
index 630d2074038ce..0d43e3b40a589 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
@@ -2504,6 +2504,16 @@
Type does not implement the collection pattern; member is is not a public instance or extension method.
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+ A method marked [DoesNotReturn] should not return.Un método marcado [DoesNotReturn] no debe devolver.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
index 7004ed29bf9d0..c6db48c2fff18 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
@@ -2504,6 +2504,16 @@
Type does not implement the collection pattern; member is is not a public instance or extension method.
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+ A method marked [DoesNotReturn] should not return.Une méthode marquée [DoesNotReturn] ne doit pas être retournée.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
index 7c7f2fd041c8c..c3138b71914a3 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
@@ -2504,6 +2504,16 @@
Type does not implement the collection pattern; member is is not a public instance or extension method.
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+ A method marked [DoesNotReturn] should not return.Un metodo contrassegnato con [DoesNotReturn] non deve essere restituito.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
index 745f3c6401b94..5b2e5a37515b6 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
@@ -2504,6 +2504,16 @@
Type does not implement the collection pattern; member is is not a public instance or extension method.
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+ A method marked [DoesNotReturn] should not return.[DoesNotReturn] とマークされたメソッドを返すことはできません。
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
index 401298a3c95e9..ab0cfb8696da9 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
@@ -2504,6 +2504,16 @@
Type does not implement the collection pattern; member is is not a public instance or extension method.
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+ A method marked [DoesNotReturn] should not return.[DoesNotReturn]으로 표시된 메서드는 반환하지 않아야 합니다.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
index 16c7fe5199756..f74263e9dd3c0 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
@@ -2504,6 +2504,16 @@
Type does not implement the collection pattern; member is is not a public instance or extension method.
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+ A method marked [DoesNotReturn] should not return.Metoda oznaczona [DoesNotReturn] nie powinna zwracać wartości.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
index 39460c7054701..7ab4cbcca83b1 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
@@ -2502,6 +2502,16 @@
Type does not implement the collection pattern; member is is not a public instance or extension method.
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+ A method marked [DoesNotReturn] should not return.Um método marcado como [DoesNotReturn] não deve ser retornado.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
index a093524636170..c74d062d9c24e 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
@@ -2504,6 +2504,16 @@
Type does not implement the collection pattern; member is is not a public instance or extension method.
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+ A method marked [DoesNotReturn] should not return.Метод, помеченный [DoesNotReturn], не должен возвращать значение.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
index 155a150a2fafe..c4bc018a7f790 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
@@ -2504,6 +2504,16 @@
Type does not implement the collection pattern; member is is not a public instance or extension method.
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+ A method marked [DoesNotReturn] should not return.[DoesNotReturn] olarak işaretlenen bir yöntem, döndürmemelidir.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
index c2ced95587fd6..c92c7bdb26154 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
@@ -2504,6 +2504,16 @@
Type does not implement the collection pattern; member is is not a public instance or extension method.
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+ A method marked [DoesNotReturn] should not return.不应返回标记为 [DoesNotReturn] 的方法。
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
index 7d1221b208a72..3dfe5d10224e4 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
@@ -2504,6 +2504,16 @@
Type does not implement the collection pattern; member is is not a public instance or extension method.
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+
+
+ A type should not be named 'record'.
+ A type should not be named 'record'.
+
+ A method marked [DoesNotReturn] should not return.標記 [DoesNotReturn] 的方法不應傳回。
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs
index d9f9f4d8bf242..aafa0bd1018cb 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs
@@ -1968,7 +1968,7 @@ public override void M(U t)
);
}
- [Fact]
+ [Fact, WorkItem(47090, "https://github.com/dotnet/roslyn/issues/47090")]
public void TypeNamedRecord()
{
var src = @"
@@ -1980,22 +1980,88 @@ record M(record r) => r;
}";
var comp = CreateCompilation(src);
comp.VerifyDiagnostics(
+ // (2,7): error CS8860: A type should not be named 'record'.
+ // class record { }
+ Diagnostic(ErrorCode.WRN_RecordNamedDisallowed, "record").WithArguments("record").WithLocation(2, 7),
// (6,24): error CS1514: { expected
// record M(record r) => r;
Diagnostic(ErrorCode.ERR_LbraceExpected, "=>").WithLocation(6, 24),
// (6,24): error CS1513: } expected
// record M(record r) => r;
Diagnostic(ErrorCode.ERR_RbraceExpected, "=>").WithLocation(6, 24),
- // (6,24): error CS1519: Invalid token '=>' in class, struct, or interface member declaration
+ // (6,24): error CS1519: Invalid token '=>' in class, record, struct, or interface member declaration
// record M(record r) => r;
Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=>").WithArguments("=>").WithLocation(6, 24),
- // (6,28): error CS1519: Invalid token ';' in class, struct, or interface member declaration
+ // (6,28): error CS1519: Invalid token ';' in class, record, struct, or interface member declaration
// record M(record r) => r;
Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(6, 28),
- // (6,28): error CS1519: Invalid token ';' in class, struct, or interface member declaration
+ // (6,28): error CS1519: Invalid token ';' in class, record, struct, or interface member declaration
// record M(record r) => r;
Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(6, 28)
);
+
+ comp = CreateCompilation(src, parseOptions: TestOptions.Regular8);
+ comp.VerifyDiagnostics(
+ // (2,7): error CS8860: A type should not be named 'record'.
+ // class record { }
+ Diagnostic(ErrorCode.WRN_RecordNamedDisallowed, "record").WithArguments("record").WithLocation(2, 7)
+ );
+ }
+
+ [Fact, WorkItem(47090, "https://github.com/dotnet/roslyn/issues/47090")]
+ public void TypeNamedRecord_Struct()
+ {
+ var src = @"
+struct record { }
+";
+ var comp = CreateCompilation(src);
+ comp.VerifyDiagnostics(
+ // (2,8): warning CS8860: A type should not be named 'record'.
+ // struct record { }
+ Diagnostic(ErrorCode.WRN_RecordNamedDisallowed, "record").WithArguments("record").WithLocation(2, 8)
+ );
+ }
+
+ [Fact, WorkItem(47090, "https://github.com/dotnet/roslyn/issues/47090")]
+ public void TypeNamedRecord_Interface()
+ {
+ var src = @"
+interface record { }
+";
+ var comp = CreateCompilation(src);
+ comp.VerifyDiagnostics(
+ // (2,11): warning CS8860: A type should not be named 'record'.
+ // interface record { }
+ Diagnostic(ErrorCode.WRN_RecordNamedDisallowed, "record").WithArguments("record").WithLocation(2, 11)
+ );
+ }
+
+ [Fact, WorkItem(47090, "https://github.com/dotnet/roslyn/issues/47090")]
+ public void TypeNamedRecord_Record()
+ {
+ var src = @"
+record record { }
+";
+ var comp = CreateCompilation(src);
+ comp.VerifyDiagnostics(
+ // (2,8): warning CS8860: A type should not be named 'record'.
+ // record record { }
+ Diagnostic(ErrorCode.WRN_RecordNamedDisallowed, "record").WithArguments("record").WithLocation(2, 8)
+ );
+ }
+
+ [Fact, WorkItem(47090, "https://github.com/dotnet/roslyn/issues/47090")]
+ public void TypeNamedRecord_Escaped()
+ {
+ var src = @"
+class @record { }
+";
+ var comp = CreateCompilation(src);
+ comp.VerifyDiagnostics(
+ // (2,7): warning CS8860: A type should not be named 'record'.
+ // class @record { }
+ Diagnostic(ErrorCode.WRN_RecordNamedDisallowed, "@record").WithArguments("record").WithLocation(2, 7)
+ );
}
[Fact]
@@ -2019,7 +2085,11 @@ public static void Main()
}
}";
var comp = CreateCompilation(src, options: TestOptions.DebugExe);
- comp.VerifyEmitDiagnostics();
+ comp.VerifyEmitDiagnostics(
+ // (2,7): warning CS8860: A type should not be named 'record'.
+ // class record { }
+ Diagnostic(ErrorCode.WRN_RecordNamedDisallowed, "record").WithArguments("record").WithLocation(2, 7)
+ );
CompileAndVerify(comp, expectedOutput: "RAN");
}
diff --git a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs
index 148dccc2a1896..d7d3393d69a5e 100644
--- a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs
+++ b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs
@@ -255,6 +255,7 @@ public void WarningLevel_2()
case ErrorCode.WRN_UnconsumedEnumeratorCancellationAttributeUsage:
case ErrorCode.WRN_UndecoratedCancellationTokenParameter:
case ErrorCode.WRN_SwitchExpressionNotExhaustiveWithWhen:
+ case ErrorCode.WRN_RecordNamedDisallowed:
Assert.Equal(1, ErrorFacts.GetWarningLevel(errorCode));
break;
case ErrorCode.WRN_MainIgnored:
@@ -398,6 +399,7 @@ public void NullableWarnings()
ErrorCode.WRN_UseDefViolationThis,
ErrorCode.WRN_UseDefViolationOut,
ErrorCode.WRN_UseDefViolation,
+ ErrorCode.WRN_RecordNamedDisallowed,
};
Assert.Contains(error, nullableUnrelatedWarnings);