diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
index 09141e3ff0c49..0d3cb75c452ac 100644
--- a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
+++ b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
@@ -4986,13 +4986,15 @@ private static void CheckRequiredMembersInObjectInitializer(
return;
}
- var requiredMembers = constructor.ContainingType.AllRequiredMembers.ToBuilder();
+ var requiredMembers = constructor.ContainingType.AllRequiredMembers;
if (requiredMembers.Count == 0)
{
return;
}
+ var requiredMembersBuilder = requiredMembers.ToBuilder();
+
if (initializers.IsDefaultOrEmpty)
{
reportMembers();
@@ -5001,24 +5003,28 @@ private static void CheckRequiredMembersInObjectInitializer(
foreach (var initializer in initializers)
{
- var (memberSymbol, initializerExpression) = initializer is BoundAssignmentOperator assignmentOperator
- ? (assignmentOperator.Left switch
- {
- // Regular initializers
- BoundObjectInitializerMember member => member.MemberSymbol,
- // Attribute initializers
- BoundPropertyAccess propertyAccess => propertyAccess.PropertySymbol,
- BoundFieldAccess fieldAccess => fieldAccess.FieldSymbol,
- _ => null
- }, assignmentOperator.Right)
- : default;
+ if (initializer is not BoundAssignmentOperator assignmentOperator)
+ {
+ continue;
+ }
+
+ var memberSymbol = assignmentOperator.Left switch
+ {
+ // Regular initializers
+ BoundObjectInitializerMember member => member.MemberSymbol,
+ // Attribute initializers
+ BoundPropertyAccess propertyAccess => propertyAccess.PropertySymbol,
+ BoundFieldAccess fieldAccess => fieldAccess.FieldSymbol,
+ // Error cases
+ _ => null
+ };
if (memberSymbol is null)
{
continue;
}
- if (!requiredMembers.TryGetValue(memberSymbol.Name, out var requiredMember))
+ if (!requiredMembersBuilder.TryGetValue(memberSymbol.Name, out var requiredMember))
{
continue;
}
@@ -5028,12 +5034,12 @@ private static void CheckRequiredMembersInObjectInitializer(
continue;
}
- requiredMembers.Remove(memberSymbol.Name);
+ requiredMembersBuilder.Remove(memberSymbol.Name);
- if (initializerExpression is BoundObjectInitializerExpressionBase)
+ if (assignmentOperator.Right is BoundObjectInitializerExpressionBase initializerExpression)
{
// Required member '{0}' must be assigned a value, it cannot use a nested member or collection initializer.
- diagnostics.Add(ErrorCode.ERR_RequiredMembersMustBeAssignment, initializerExpression.Syntax.Location, requiredMember);
+ diagnostics.Add(ErrorCode.ERR_RequiredMembersMustBeAssignedValue, initializerExpression.Syntax.Location, requiredMember);
}
}
@@ -5049,7 +5055,7 @@ void reportMembers()
_ => creationSyntax.Location
};
- foreach (var (_, member) in requiredMembers)
+ foreach (var (_, member) in requiredMembersBuilder)
{
// Required member '{0}' must be set in the object initializer or attribute constructor.
diagnostics.Add(ErrorCode.ERR_RequiredMemberMustBeSet, location, member);
@@ -5847,6 +5853,8 @@ internal bool TryPerformConstructorOverloadResolution(
diagnostics.AddDependencies(useSiteInfo);
foreach (var diagnostic in useSiteInfo.Diagnostics)
{
+ // We don't want to report this error here because we'll report ERR_RequiredMembersBaseTypeInvalid. That error is suppressable by the
+ // user using the `SetsRequiredMembers` attribute on the constructor, so reporting this error would prevent that from working.
if ((ErrorCode)diagnostic.Code == ErrorCode.ERR_RequiredMembersInvalid)
{
continue;
diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index 37e085f41196f..4d375d06462c3 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -7010,7 +7010,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
Required member '{0}' must be set in the object initializer or attribute constructor.
-
+
Required member '{0}' must be assigned a value, it cannot use a nested member or collection initializer.
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
index 475e6d1e0eed2..50af936c9ead5 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@@ -2059,7 +2059,7 @@ internal enum ErrorCode
ERR_ExplicitRequiredMember = 9504,
ERR_RequiredMemberMustBeSettable = 9505,
ERR_RequiredMemberMustBeSet = 9506,
- ERR_RequiredMembersMustBeAssignment = 9507,
+ ERR_RequiredMembersMustBeAssignedValue = 9507,
ERR_RequiredMembersInvalid = 9508,
ERR_RequiredMembersBaseTypeInvalid = 9509,
}
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
index aa0068593c057..bf9303a671c24 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
@@ -1182,7 +1182,7 @@
The required members list for '{0}' is malformed and cannot be interpreted.
-
+ Required member '{0}' must be assigned a value, it cannot use a nested member or collection initializer.Required member '{0}' must be assigned a value, it cannot use a nested member or collection initializer.
@@ -11534,4 +11534,4 @@ Pokud chcete odstranit toto varování, můžete místo toho použít /reference