diff --git a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs index 205fc419798db..4db2b16d274eb 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs +++ b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs @@ -2357,7 +2357,7 @@ internal static string ERR_CantChangeAccessOnOverride { } /// - /// Looks up a localized string similar to '{0}' must {2}return by reference to match overridden member '{1}'. + /// Looks up a localized string similar to '{0}' must match by reference return of overridden member '{1}'. /// internal static string ERR_CantChangeRefReturnOnOverride { get { @@ -2717,7 +2717,7 @@ internal static string ERR_CloseUnimplementedInterfaceMemberStatic { } /// - /// Looks up a localized string similar to '{0}' does not implement interface member '{1}'. '{2}' cannot implement '{1}' because it does not return by {3}. + /// Looks up a localized string similar to '{0}' does not implement interface member '{1}'. '{2}' cannot implement '{1}' because it does not have matching return by reference.. /// internal static string ERR_CloseUnimplementedInterfaceMemberWrongRefReturn { get { @@ -7100,20 +7100,11 @@ internal static string ERR_OutputWriteFailed { } /// - /// Looks up a localized string similar to '{0}' cannot define overloaded methods that differ only on ref and out. + /// Looks up a localized string similar to '{0}' cannot define an overloaded {1} that differs only on parameter modifiers '{2}' and '{3}'. /// - internal static string ERR_OverloadRefOut { + internal static string ERR_OverloadRefKind { get { - return ResourceManager.GetString("ERR_OverloadRefOut", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Cannot define overloaded constructor '{0}' because it differs from another constructor only on ref and out. - /// - internal static string ERR_OverloadRefOutCtor { - get { - return ResourceManager.GetString("ERR_OverloadRefOutCtor", resourceCulture); + return ResourceManager.GetString("ERR_OverloadRefKind", resourceCulture); } } @@ -10349,6 +10340,15 @@ internal static string IDS_SK_ALIAS { } } + /// + /// Looks up a localized string similar to constructor. + /// + internal static string IDS_SK_CONSTRUCTOR { + get { + return ResourceManager.GetString("IDS_SK_CONSTRUCTOR", resourceCulture); + } + } + /// /// Looks up a localized string similar to event. /// diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 5ac5672142263..4da81b22e4648 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -288,6 +288,9 @@ extern alias + + constructor + foreach iteration variable @@ -1817,8 +1820,8 @@ If such a class is used as a base class and if the deriving class defines a dest Cannot specify only Out attribute on a ref parameter. Use both In and Out attributes, or neither. - - '{0}' cannot define overloaded methods that differ only on ref and out + + '{0}' cannot define an overloaded {1} that differs only on parameter modifiers '{2}' and '{3}' Literal of type double cannot be implicitly converted to type '{1}'; use an '{0}' suffix to create a literal of this type @@ -3731,9 +3734,6 @@ You should consider suppressing the warning only if you're sure that you don't w Using 'is' to test compatibility with 'dynamic' is essentially identical to testing compatibility with 'Object' - - Cannot define overloaded constructor '{0}' because it differs from another constructor only on ref and out - Cannot use 'yield' in top-level script code @@ -4730,7 +4730,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ Properties which return by reference cannot have set accessors - '{0}' must {2}return by reference to match overridden member '{1}' + '{0}' must match by reference return of overridden member '{1}' By-reference returns may only be used in methods that return by reference @@ -4742,7 +4742,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ The return expression must be of type '{0}' because this method returns by reference - '{0}' does not implement interface member '{1}'. '{2}' cannot implement '{1}' because it does not return by {3} + '{0}' does not implement interface member '{1}'. '{2}' cannot implement '{1}' because it does not have matching return by reference. The body of '{0}' cannot be an iterator block because '{0}' returns by reference diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index ad453ec653a14..754c0d9e8ad79 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -452,7 +452,7 @@ internal enum ErrorCode WRN_EqualityOpWithoutEquals = 660, WRN_EqualityOpWithoutGetHashCode = 661, ERR_OutAttrOnRefParam = 662, - ERR_OverloadRefOut = 663, + ERR_OverloadRefKind = 663, ERR_LiteralDoubleCast = 664, WRN_IncorrectBooleanAssg = 665, ERR_ProtectedInStruct = 666, @@ -584,7 +584,7 @@ internal enum ErrorCode ERR_ExpressionTreeContainsBadCoalesce = 845, ERR_ArrayInitializerExpected = 846, ERR_ArrayInitializerIncorrectLength = 847, - ERR_OverloadRefOutCtor = 851, + // ERR_OverloadRefOutCtor = 851, Replaced By ERR_OverloadRefKind ERR_ExpressionTreeContainsNamedArgument = 853, ERR_ExpressionTreeContainsOptionalArgument = 854, ERR_ExpressionTreeContainsIndexedProperty = 855, diff --git a/src/Compilers/CSharp/Portable/Errors/MessageID.cs b/src/Compilers/CSharp/Portable/Errors/MessageID.cs index 0c15144128086..6f0d23b247f96 100644 --- a/src/Compilers/CSharp/Portable/Errors/MessageID.cs +++ b/src/Compilers/CSharp/Portable/Errors/MessageID.cs @@ -10,6 +10,7 @@ internal enum MessageID { None = 0, MessageBase = 1200, + IDS_SK_METHOD = MessageBase + 2000, IDS_SK_TYPE = MessageBase + 2001, IDS_SK_NAMESPACE = MessageBase + 2002, @@ -23,6 +24,8 @@ internal enum MessageID IDS_SK_ALIAS = MessageBase + 2010, //IDS_SK_EXTERNALIAS = MessageBase + 2011, IDS_SK_LABEL = MessageBase + 2012, + IDS_SK_CONSTRUCTOR = MessageBase + 2013, + IDS_NULL = MessageBase + 10001, //IDS_RELATEDERROR = MessageBase + 10002, //IDS_RELATEDWARNING = MessageBase + 10003, @@ -129,7 +132,6 @@ internal enum MessageID IDS_ThrowExpression = MessageBase + 12717, IDS_FeatureReadonlyReferences = MessageBase + 12718, - } // Message IDs may refer to strings that need to be localized. diff --git a/src/Compilers/CSharp/Portable/Symbols/MemberSignatureComparer.cs b/src/Compilers/CSharp/Portable/Symbols/MemberSignatureComparer.cs index 0a87f80058880..cd440de323eef 100644 --- a/src/Compilers/CSharp/Portable/Symbols/MemberSignatureComparer.cs +++ b/src/Compilers/CSharp/Portable/Symbols/MemberSignatureComparer.cs @@ -41,7 +41,7 @@ internal class MemberSignatureComparer : IEqualityComparer considerExplicitlyImplementedInterfaces: false, considerReturnType: true, considerTypeConstraints: false, - considerRefOutDifference: true, + considerRefKindDifferences: true, considerCallingConvention: true, considerCustomModifiers: false); @@ -64,7 +64,7 @@ internal class MemberSignatureComparer : IEqualityComparer considerReturnType: true, considerTypeConstraints: false, // constraints are checked by caller instead considerCallingConvention: true, - considerRefOutDifference: true, + considerRefKindDifferences: true, considerCustomModifiers: false); /// @@ -78,7 +78,7 @@ internal class MemberSignatureComparer : IEqualityComparer considerReturnType: false, considerTypeConstraints: false, considerCallingConvention: false, - considerRefOutDifference: true, + considerRefKindDifferences: true, considerCustomModifiers: false); //shouldn't actually matter for source members /// @@ -95,7 +95,7 @@ internal class MemberSignatureComparer : IEqualityComparer considerReturnType: false, considerTypeConstraints: false, considerCallingConvention: false, - considerRefOutDifference: false, + considerRefKindDifferences: false, considerCustomModifiers: false); //shouldn't actually matter for source members /// @@ -107,7 +107,7 @@ internal class MemberSignatureComparer : IEqualityComparer considerReturnType: false, considerTypeConstraints: false, considerCallingConvention: false, //ignore static-ness - considerRefOutDifference: true, + considerRefKindDifferences: true, considerCustomModifiers: false); /// @@ -120,7 +120,7 @@ internal class MemberSignatureComparer : IEqualityComparer considerReturnType: true, considerTypeConstraints: false, considerCallingConvention: false, //ignore static-ness - considerRefOutDifference: false, + considerRefKindDifferences: false, considerCustomModifiers: false, ignoreDynamic: true, ignoreTupleNames: false); @@ -135,7 +135,7 @@ internal class MemberSignatureComparer : IEqualityComparer considerReturnType: true, considerTypeConstraints: false, considerCallingConvention: false, //ignore static-ness - considerRefOutDifference: false, + considerRefKindDifferences: false, considerCustomModifiers: false, ignoreDynamic: true, ignoreTupleNames: true); @@ -151,7 +151,7 @@ internal class MemberSignatureComparer : IEqualityComparer considerReturnType: true, considerTypeConstraints: false, considerCallingConvention: false, //ignore static-ness - considerRefOutDifference: true, + considerRefKindDifferences: true, considerCustomModifiers: false); /// @@ -165,7 +165,7 @@ internal class MemberSignatureComparer : IEqualityComparer considerReturnType: true, considerTypeConstraints: false, considerCallingConvention: false, //ignore static-ness - considerRefOutDifference: true, + considerRefKindDifferences: true, considerCustomModifiers: true); /// @@ -178,7 +178,7 @@ internal class MemberSignatureComparer : IEqualityComparer considerReturnType: false, considerTypeConstraints: false, considerCallingConvention: false, //ignore static-ness - considerRefOutDifference: false, + considerRefKindDifferences: false, considerCustomModifiers: false); /// @@ -193,7 +193,7 @@ internal class MemberSignatureComparer : IEqualityComparer considerReturnType: true, considerTypeConstraints: false, considerCallingConvention: true, - considerRefOutDifference: false, + considerRefKindDifferences: false, considerCustomModifiers: true); /// @@ -207,7 +207,7 @@ internal class MemberSignatureComparer : IEqualityComparer considerReturnType: true, considerTypeConstraints: false, considerCallingConvention: true, - considerRefOutDifference: true, + considerRefKindDifferences: true, considerCustomModifiers: true); /// @@ -220,7 +220,7 @@ internal class MemberSignatureComparer : IEqualityComparer considerReturnType: true, considerTypeConstraints: false, // constraints are checked by caller instead considerCallingConvention: true, - considerRefOutDifference: false, + considerRefKindDifferences: false, considerCustomModifiers: true); // NOTE: Not used anywhere. Do we still need to keep it? @@ -234,7 +234,7 @@ internal class MemberSignatureComparer : IEqualityComparer considerReturnType: true, considerTypeConstraints: true, considerCallingConvention: true, - considerRefOutDifference: true, + considerRefKindDifferences: true, considerCustomModifiers: false); //intended for source types /// @@ -246,7 +246,7 @@ internal class MemberSignatureComparer : IEqualityComparer considerReturnType: true, considerTypeConstraints: false, considerCallingConvention: true, - considerRefOutDifference: true, + considerRefKindDifferences: true, considerCustomModifiers: true); //if it was a true explicit impl, we expect it to remain so after retargeting /// @@ -259,7 +259,7 @@ internal class MemberSignatureComparer : IEqualityComparer considerReturnType: false, considerTypeConstraints: false, considerCallingConvention: false, //ignore static-ness - considerRefOutDifference: true, + considerRefKindDifferences: true, considerCustomModifiers: false); // Compare the "unqualified" part of the member name (no explicit part) @@ -277,8 +277,8 @@ internal class MemberSignatureComparer : IEqualityComparer // Compare the full calling conventions. Still compares varargs if false. private readonly bool _considerCallingConvention; - // True to consider RefKind.Ref and RefKind.Out different, false to consider them the same. - private readonly bool _considerRefOutDifference; + // True to consider RefKind differences, false to consider them the same. + private readonly bool _considerRefKindDifferences; // Consider custom modifiers on/in parameters and return types (if return is considered). private readonly bool _considerCustomModifiers; @@ -295,7 +295,7 @@ private MemberSignatureComparer( bool considerReturnType, bool considerTypeConstraints, bool considerCallingConvention, - bool considerRefOutDifference, + bool considerRefKindDifferences, bool considerCustomModifiers, bool ignoreDynamic = true, bool ignoreTupleNames = true) @@ -307,7 +307,7 @@ private MemberSignatureComparer( _considerReturnType = considerReturnType; _considerTypeConstraints = considerTypeConstraints; _considerCallingConvention = considerCallingConvention; - _considerRefOutDifference = considerRefOutDifference; + _considerRefKindDifferences = considerRefKindDifferences; _considerCustomModifiers = considerCustomModifiers; _ignoreDynamic = ignoreDynamic; _ignoreTupleNames = ignoreTupleNames; @@ -355,13 +355,14 @@ public bool Equals(Symbol member1, Symbol member2) var typeMap1 = GetTypeMap(member1); var typeMap2 = GetTypeMap(member2); - if (_considerReturnType && !HaveSameReturnTypes(member1, typeMap1, member2, typeMap2, _considerCustomModifiers, _ignoreDynamic, _ignoreTupleNames)) + if (_considerReturnType && !HaveSameReturnTypes(member1, typeMap1, member2, typeMap2, + _considerCustomModifiers, _ignoreDynamic, _ignoreTupleNames)) { return false; } if (member1.GetParameterCount() > 0 && !HaveSameParameterTypes(member1.GetParameters(), typeMap1, member2.GetParameters(), typeMap2, - _considerRefOutDifference, _considerCustomModifiers, _ignoreDynamic, _ignoreTupleNames)) + _considerRefKindDifferences, _considerCustomModifiers, _ignoreDynamic, _ignoreTupleNames)) { return false; } @@ -482,7 +483,7 @@ private static bool HaveSameReturnTypes(Symbol member1, TypeMap typeMap1, Symbol member2.GetTypeOrReturnType(out refKind2, out unsubstitutedReturnType2, out returnTypeCustomModifiers2, out refCustomModifiers2); // short-circuit type map building in the easiest cases - if ((refKind1 != RefKind.None) != (refKind2 != RefKind.None)) + if (refKind1 != refKind2) { return false; } @@ -627,7 +628,7 @@ private static void SubstituteConstraintTypes(ImmutableArray types, } private static bool HaveSameParameterTypes(ImmutableArray params1, TypeMap typeMap1, ImmutableArray params2, TypeMap typeMap2, - bool considerRefOutDifference, bool considerCustomModifiers, bool ignoreDynamic, bool ignoreTupleNames) + bool considerRefKindDifferences, bool considerCustomModifiers, bool ignoreDynamic, bool ignoreTupleNames) { Debug.Assert(params1.Length == params2.Length); @@ -659,7 +660,7 @@ private static bool HaveSameParameterTypes(ImmutableArray param var refKind2 = param2.RefKind; // Metadata signatures don't distinguish ref/out, but C# does - even when comparing metadata method signatures. - if (considerRefOutDifference) + if (considerRefKindDifferences) { if (refKind1 != refKind2) { diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index 67128a3378c8a..a1199e22e6c24 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -1538,23 +1538,29 @@ private void ReportMethodSignatureCollision(DiagnosticBag diagnostics, SourceMet return; } - if (DifferByOutOrRef(method1, method2)) - { - // '{0}' cannot define overloaded methods that differ only on ref and out - ErrorCode errorCode = method1.MethodKind == MethodKind.Constructor ? - ErrorCode.ERR_OverloadRefOutCtor : - ErrorCode.ERR_OverloadRefOut; - diagnostics.Add(errorCode, method1.Locations[0], this); - } - else + Debug.Assert(method1.ParameterCount == method2.ParameterCount); + + for (int i = 0; i < method1.ParameterCount; i++) { - // Special case: if there are two destructors, use the destructor syntax instead of "Finalize" - var methodName = (method1.MethodKind == MethodKind.Destructor && method2.MethodKind == MethodKind.Destructor) ? - "~" + this.Name : - method1.Name; - // Type '{1}' already defines a member called '{0}' with the same parameter types - diagnostics.Add(ErrorCode.ERR_MemberAlreadyExists, method1.Locations[0], methodName, this); + var refKind1 = method1.Parameters[i].RefKind; + var refKind2 = method2.Parameters[i].RefKind; + + if (refKind1 != refKind2) + { + // '{0}' cannot define an overloaded {1} that differs only on parameter modifiers '{2}' and '{3}' + var methodKind = method1.MethodKind == MethodKind.Constructor ? MessageID.IDS_SK_CONSTRUCTOR : MessageID.IDS_SK_METHOD; + diagnostics.Add(ErrorCode.ERR_OverloadRefKind, method1.Locations[0], this, methodKind.Localize(), refKind1.ToDisplayString(), refKind2.ToDisplayString()); + + return; + } } + + // Special case: if there are two destructors, use the destructor syntax instead of "Finalize" + var methodName = (method1.MethodKind == MethodKind.Destructor && method2.MethodKind == MethodKind.Destructor) ? + "~" + this.Name : + method1.Name; + // Type '{1}' already defines a member called '{0}' with the same parameter types + diagnostics.Add(ErrorCode.ERR_MemberAlreadyExists, method1.Locations[0], methodName, this); } private void CheckIndexerNameConflicts(DiagnosticBag diagnostics, Dictionary> membersByName) @@ -2436,23 +2442,7 @@ private static ImmutableArray Remove(ImmutableArray symbols, Sym } return builder.ToImmutableAndFree(); } - - private static bool DifferByOutOrRef(SourceMethodSymbol m1, SourceMethodSymbol m2) - { - var pl1 = m1.Parameters; - var pl2 = m2.Parameters; - int n = pl1.Length; - for (int i = 0; i < n; i++) - { - if (pl1[i].RefKind != pl2[i].RefKind) - { - return true; - } - } - - return false; - } - + /// /// Report an error if a member (other than a method) exists with the same name /// as the property accessor, or if a method exists with the same name and signature. diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol_ImplementationChecks.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol_ImplementationChecks.cs index 5b631112e8b88..639c663436bdc 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol_ImplementationChecks.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol_ImplementationChecks.cs @@ -704,9 +704,9 @@ private static void CheckOverrideMember(Symbol overridingMember, OverriddenOrHid TypeSymbol overriddenMemberType = overriddenProperty.Type; // Check for mismatched byref returns and return type. Ignore custom modifiers, because this diagnostic is based on the C# semantics. - if ((overridingProperty.RefKind != RefKind.None) != (overriddenProperty.RefKind != RefKind.None)) + if (overridingProperty.RefKind != overriddenProperty.RefKind) { - diagnostics.Add(ErrorCode.ERR_CantChangeRefReturnOnOverride, overridingMemberLocation, overridingMember, overriddenMember, overridingProperty.RefKind != RefKind.None ? "not " : ""); + diagnostics.Add(ErrorCode.ERR_CantChangeRefReturnOnOverride, overridingMemberLocation, overridingMember, overriddenMember); suppressAccessors = true; //we get really unhelpful errors from the accessor if the ref kind is mismatched } else if (!overridingMemberType.Equals(overriddenMemberType, TypeCompareKind.AllIgnoreOptions)) @@ -760,9 +760,9 @@ private static void CheckOverrideMember(Symbol overridingMember, OverriddenOrHid var overriddenMethod = (MethodSymbol)overriddenMember; // Check for mismatched byref returns and return type. Ignore custom modifiers, because this diagnostic is based on the C# semantics. - if ((overridingMethod.RefKind != RefKind.None) != (overriddenMethod.RefKind != RefKind.None)) + if (overridingMethod.RefKind != overriddenMethod.RefKind) { - diagnostics.Add(ErrorCode.ERR_CantChangeRefReturnOnOverride, overridingMemberLocation, overridingMember, overriddenMember, overridingMethod.RefKind != RefKind.None ? "not " : ""); + diagnostics.Add(ErrorCode.ERR_CantChangeRefReturnOnOverride, overridingMemberLocation, overridingMember, overriddenMember); } else if (!MemberSignatureComparer.HaveSameReturnTypes(overridingMethod, overriddenMethod, considerCustomModifiers: false)) { diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs index acd51a52b7906..ea5c79a6b760e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs @@ -1162,11 +1162,11 @@ private static void ReportImplicitImplementationMismatchDiagnostics(Symbol inter switch (closestMismatch.Kind) { case SymbolKind.Method: - hasRefReturnMismatch = (((MethodSymbol)closestMismatch).RefKind != RefKind.None) != (interfaceMemberRefKind != RefKind.None); + hasRefReturnMismatch = ((MethodSymbol)closestMismatch).RefKind != interfaceMemberRefKind; break; case SymbolKind.Property: - hasRefReturnMismatch = (((PropertySymbol)closestMismatch).RefKind != RefKind.None) != (interfaceMemberRefKind != RefKind.None); + hasRefReturnMismatch = ((PropertySymbol)closestMismatch).RefKind != interfaceMemberRefKind; break; } @@ -1179,7 +1179,7 @@ private static void ReportImplicitImplementationMismatchDiagnostics(Symbol inter } else if (hasRefReturnMismatch) { - diagnostics.Add(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, interfaceLocation, implementingType, interfaceMember, closestMismatch, interfaceMemberRefKind != RefKind.None ? "reference" : "value"); + diagnostics.Add(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, interfaceLocation, implementingType, interfaceMember, closestMismatch); } else { diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs index c6a821da81965..99d10dcad30e6 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs @@ -4955,7 +4955,7 @@ internal enum ErrorCode WRN_EqualityOpWithoutEquals = 660, WRN_EqualityOpWithoutGetHashCode = 661, ERR_OutAttrOnRefParam = 662, - ERR_OverloadRefOut = 663, + ERR_OverloadRefKind = 663, ERR_LiteralDoubleCast = 664, WRN_IncorrectBooleanAssg = 665, ERR_ProtectedInStruct = 666, @@ -5084,7 +5084,7 @@ internal enum ErrorCode ERR_ExpressionTreeContainsBadCoalesce = 845, ERR_ArrayInitializerExpected = 846, ERR_ArrayInitializerIncorrectLength = 847, - ERR_OverloadRefOutCtor = 851, + // ERR_OverloadRefOutCtor = 851, Replaced By ERR_OverloadRefKind ERR_ExpressionTreeContainsNamedArgument = 853, ERR_ExpressionTreeContainsOptionalArgument = 854, ERR_ExpressionTreeContainsIndexedProperty = 855, diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs index 670f2cb31fe7a..f47114e5a3fbc 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs @@ -1321,5 +1321,39 @@ public static void Main(string[] args) // since the runtime can distinguish signatures with different modopts. verifier.VerifyDiagnostics(); } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void OverloadsWithDifferentParameterModifiers_Ref_RefReadOnly() + { + var text = @" +abstract class TestClass +{ + public void Method(ref int x) { } + public void Method(ref readonly int x) { } +}"; + + var comp = CreateCompilationWithMscorlib(text).VerifyDiagnostics( + // (5,17): error CS0663: 'TestClass' cannot define an overloaded method that differs only on parameter modifiers 'ref readonly' and 'ref' + // public void Method(ref readonly int x) { } + Diagnostic(ErrorCode.ERR_OverloadRefKind, "Method").WithArguments("TestClass", "method", "ref readonly", "ref").WithLocation(5, 17)); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void OverloadsWithDifferentParameterModifiers_Out_RefReadOnly() + { + var text = @" +abstract class TestClass +{ + public void Method(out int x) { x = 0; } + public void Method(ref readonly int x) { } +}"; + + var comp = CreateCompilationWithMscorlib(text).VerifyDiagnostics( + // (5,17): error CS0663: 'TestClass' cannot define an overloaded method that differs only on parameter modifiers 'ref readonly' and 'out' + // public void Method(ref readonly int x) { } + Diagnostic(ErrorCode.ERR_OverloadRefKind, "Method").WithArguments("TestClass", "method", "ref readonly", "out").WithLocation(5, 17)); + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InheritanceBindingTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InheritanceBindingTests.cs index 05292bcf45a0b..bd45b9401b8be 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/InheritanceBindingTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InheritanceBindingTests.cs @@ -1273,12 +1273,12 @@ class Derived : Base "; CreateCompilationWithMscorlib45(text).VerifyDiagnostics( - // (13,29): error CS8148: 'Derived.Method1()' must not return by reference to match overridden member 'Base.Method1()' + // (13,29): error CS8148: 'Derived.Method1()' must match by reference return of overridden member 'Base.Method1()' // public override ref int Method1() { return ref field; } - Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method1").WithArguments("Derived.Method1()", "Base.Method1()", "not ").WithLocation(13, 29), - // (14,25): error CS8148: 'Derived.Method2(ref int)' must return by reference to match overridden member 'Base.Method2(ref int)' + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method1").WithArguments("Derived.Method1()", "Base.Method1()").WithLocation(13, 29), + // (14,25): error CS8148: 'Derived.Method2(ref int)' must match by reference return of overridden member 'Base.Method2(ref int)' // public override int Method2(ref int i) { return i; } - Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method2").WithArguments("Derived.Method2(ref int)", "Base.Method2(ref int)", "").WithLocation(14, 25)); + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method2").WithArguments("Derived.Method2(ref int)", "Base.Method2(ref int)").WithLocation(14, 25)); } [Fact] @@ -1418,12 +1418,12 @@ class Derived : Base } "; CreateCompilationWithMscorlib45(text).VerifyDiagnostics( - // (15,29): error CS8148: 'Derived.Proprty1' must not return by reference to match overridden member 'Base.Proprty1' + // (15,29): error CS8148: 'Derived.Proprty1' must match by reference return of overridden member 'Base.Proprty1' // public override ref int Proprty1 { get { return ref field; } } - Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Proprty1").WithArguments("Derived.Proprty1", "Base.Proprty1", "not ").WithLocation(15, 29), - // (16,25): error CS8148: 'Derived.Property2' must return by reference to match overridden member 'Base.Property2' + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Proprty1").WithArguments("Derived.Proprty1", "Base.Proprty1").WithLocation(15, 29), + // (16,25): error CS8148: 'Derived.Property2' must match by reference return of overridden member 'Base.Property2' // public override int Property2 { get { return 0; } } - Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Property2").WithArguments("Derived.Property2", "Base.Property2", "").WithLocation(16, 25)); + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Property2").WithArguments("Derived.Property2", "Base.Property2").WithLocation(16, 25)); } [Fact] @@ -1477,12 +1477,12 @@ class Derived : Base } "; CreateCompilationWithMscorlib45(text).VerifyDiagnostics( - // (15,29): error CS8148: 'Derived.this[int, int]' must not return by reference to match overridden member 'Base.this[int, int]' + // (15,29): error CS8148: 'Derived.this[int, int]' must match by reference return of overridden member 'Base.this[int, int]' // public override ref int this[int x, int y] { get { return ref field; } } - Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "this").WithArguments("Derived.this[int, int]", "Base.this[int, int]", "not ").WithLocation(15, 29), - // (16,25): error CS8148: 'Derived.this[int, string]' must return by reference to match overridden member 'Base.this[int, string]' + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "this").WithArguments("Derived.this[int, int]", "Base.this[int, int]").WithLocation(15, 29), + // (16,25): error CS8148: 'Derived.this[int, string]' must match by reference return of overridden member 'Base.this[int, string]' // public override int this[int x, string y] { get { return field; } } - Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "this").WithArguments("Derived.this[int, string]", "Base.this[int, string]", "").WithLocation(16, 25)); + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "this").WithArguments("Derived.this[int, string]", "Base.this[int, string]").WithLocation(16, 25)); } /// @@ -2053,27 +2053,27 @@ class Derived : Base // (16,16): warning CS0114: 'Derived.Method3()' hides inherited member 'Base.Method3()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword. // public int Method3() { return 0; } //wrong return type Diagnostic(ErrorCode.WRN_NewOrOverrideExpected, "Method3").WithArguments("Derived.Method3()", "Base.Method3()").WithLocation(16, 16), - // (18,28): error CS8148: 'Derived.Method5(ref object)' must return by reference to match overridden member 'Base.Method5(ref object)' + // (18,28): error CS8148: 'Derived.Method5(ref object)' must match by reference return of overridden member 'Base.Method5(ref object)' // public override object Method5(ref object o) { return null; } //wrong by-value return - Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method5").WithArguments("Derived.Method5(ref object)", "Base.Method5(ref object)", "").WithLocation(18, 28), - // (19,32): error CS8148: 'Derived.Method6(ref object)' must not return by reference to match overridden member 'Base.Method6(ref object)' + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method5").WithArguments("Derived.Method5(ref object)", "Base.Method5(ref object)").WithLocation(18, 28), + // (19,32): error CS8148: 'Derived.Method6(ref object)' must match by reference return of overridden member 'Base.Method6(ref object)' // public override ref object Method6(ref object o) { return ref o; } //wrong by-ref return - Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method6").WithArguments("Derived.Method6(ref object)", "Base.Method6(ref object)", "not ").WithLocation(19, 32), + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method6").WithArguments("Derived.Method6(ref object)", "Base.Method6(ref object)").WithLocation(19, 32), // (15,19): warning CS0114: 'Derived.Method2()' hides inherited member 'Base.Method2()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword. // public object Method2() { return null; } //missed override keyword Diagnostic(ErrorCode.WRN_NewOrOverrideExpected, "Method2").WithArguments("Derived.Method2()", "Base.Method2()").WithLocation(15, 19), - // (12,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Method3()' - // class Derived : Base - Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Method3()").WithLocation(12, 7), // (12,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Method2()' // class Derived : Base Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Method2()").WithLocation(12, 7), - // (12,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Method1()' - // class Derived : Base - Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Method1()").WithLocation(12, 7), // (12,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Method4(int)' // class Derived : Base - Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Method4(int)").WithLocation(12, 7)); + Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Method4(int)").WithLocation(12, 7), + // (12,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Method3()' + // class Derived : Base + Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Method3()").WithLocation(12, 7), + // (12,7): error CS0534: 'Derived' does not implement inherited abstract member 'Base.Method1()' + // class Derived : Base + Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Method1()").WithLocation(12, 7)); } [Fact] @@ -2133,12 +2133,12 @@ public override object Property7 { set { } } // (31,40): error CS0545: 'Derived.Property9.get': cannot override because 'Base.Property9' does not have an overridable get accessor // public override object Property9 { get { return null; } } Diagnostic(ErrorCode.ERR_NoGetToOverride, "get").WithArguments("Derived.Property9.get", "Base.Property9").WithLocation(31, 40), - // (35,32): error CS8148: 'Derived.Property10' must not return by reference to match overridden member 'Base.Property10' + // (35,32): error CS8148: 'Derived.Property10' must match by reference return of overridden member 'Base.Property10' // public override ref object Property10 { get { return ref o; } } - Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Property10").WithArguments("Derived.Property10", "Base.Property10", "not ").WithLocation(35, 32), - // (36,28): error CS8148: 'Derived.Property11' must return by reference to match overridden member 'Base.Property11' + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Property10").WithArguments("Derived.Property10", "Base.Property10").WithLocation(35, 32), + // (36,28): error CS8148: 'Derived.Property11' must match by reference return of overridden member 'Base.Property11' // public override object Property11 { get { return null; } } - Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Property11").WithArguments("Derived.Property11", "Base.Property11", "").WithLocation(36, 28), + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Property11").WithArguments("Derived.Property11", "Base.Property11").WithLocation(36, 28), // (22,19): warning CS0114: 'Derived.Property2' hides inherited member 'Base.Property2'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword. // public object Property2 { get; set; } //missed override keyword Diagnostic(ErrorCode.WRN_NewOrOverrideExpected, "Property2").WithArguments("Derived.Property2", "Base.Property2").WithLocation(22, 19), @@ -2180,6 +2180,7 @@ public override object Property7 { set { } } Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "Derived").WithArguments("Derived", "Base.Property10.get").WithLocation(19, 7)); } + [Fact] public void TestNoImplementationOfAbstractIndexer() { @@ -2240,12 +2241,12 @@ class Derived : Base // (31,67): error CS0545: 'Derived.this[string, int, int, int].get': cannot override because 'Base.this[string, int, int, int]' does not have an overridable get accessor // public override object this[string w, int x, int y , int z] { get { return null; } } Diagnostic(ErrorCode.ERR_NoGetToOverride, "get").WithArguments("Derived.this[string, int, int, int].get", "Base.this[string, int, int, int]").WithLocation(31, 67), - // (35,32): error CS8082: 'Derived.this[string, int, int, string]' must not have a by-reference return to match overridden member 'Base.this[string, int, int, string]' + // (35,32): error CS8148: 'Derived.this[string, int, int, string]' must match by reference return of overridden member 'Base.this[string, int, int, string]' // public override ref object this[string w, int x, int y, string z] { get { return ref o; } } - Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "this").WithArguments("Derived.this[string, int, int, string]", "Base.this[string, int, int, string]", "not ").WithLocation(35, 32), - // (36,28): error CS8082: 'Derived.this[string, int, string, int]' must have a by-reference return to match overridden member 'Base.this[string, int, string, int]' + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "this").WithArguments("Derived.this[string, int, int, string]", "Base.this[string, int, int, string]").WithLocation(35, 32), + // (36,28): error CS8148: 'Derived.this[string, int, string, int]' must match by reference return of overridden member 'Base.this[string, int, string, int]' // public override object this[string w, int x, string y, int z] { get; } - Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "this").WithArguments("Derived.this[string, int, string, int]", "Base.this[string, int, string, int]", "").WithLocation(36, 28), + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "this").WithArguments("Derived.this[string, int, string, int]", "Base.this[string, int, string, int]").WithLocation(36, 28), // (22,19): warning CS0114: 'Derived.this[int, int, int, string]' hides inherited member 'Base.this[int, int, int, string]'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword. // public object this[int w, int x, int y , string z] { get { return 0; } set { } } //missed override keyword Diagnostic(ErrorCode.WRN_NewOrOverrideExpected, "this").WithArguments("Derived.this[int, int, int, string]", "Base.this[int, int, int, string]").WithLocation(22, 19), @@ -2486,15 +2487,15 @@ class Class : Interface } "; CreateCompilationWithMscorlib45(text).VerifyDiagnostics( - // (10,15): error CS8152: 'Class' does not implement interface member 'Interface.Method4(ref object)'. 'Class.Method4(ref object)' cannot implement 'Interface.Method4(ref object)' because it does not return by value + // (10,15): error CS8152: 'Class' does not implement interface member 'Interface.Method4(ref object)'. 'Class.Method4(ref object)' cannot implement 'Interface.Method4(ref object)' because it does not have matching return by reference. // class Class : Interface - Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.Method4(ref object)", "Class.Method4(ref object)", "value").WithLocation(10, 15), + Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.Method4(ref object)", "Class.Method4(ref object)").WithLocation(10, 15), // (10,15): error CS0535: 'Class' does not implement interface member 'Interface.Method2(int)' // class Class : Interface Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Method2(int)").WithLocation(10, 15), - // (10,15): error CS8152: 'Class' does not implement interface member 'Interface.Method3(ref object)'. 'Class.Method3(ref object)' cannot implement 'Interface.Method3(ref object)' because it does not return by reference + // (10,15): error CS8152: 'Class' does not implement interface member 'Interface.Method3(ref object)'. 'Class.Method3(ref object)' cannot implement 'Interface.Method3(ref object)' because it does not have matching return by reference. // class Class : Interface - Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.Method3(ref object)", "Class.Method3(ref object)", "reference").WithLocation(10, 15), + Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.Method3(ref object)", "Class.Method3(ref object)").WithLocation(10, 15), // (10,15): error CS0535: 'Class' does not implement interface member 'Interface.Method1()' // class Class : Interface Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Method1()").WithLocation(10, 15)); @@ -2550,12 +2551,12 @@ public object Property5 { set { } } // (17,15): error CS0535: 'Class' does not implement interface member 'Interface.Property7.set' // class Class : Interface Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Property7.set").WithLocation(17, 15), - // (17,15): error CS8152: 'Class' does not implement interface member 'Interface.Property8'. 'Class.Property8' cannot implement 'Interface.Property8' because it does not return by reference + // (17,15): error CS8152: 'Class' does not implement interface member 'Interface.Property8'. 'Class.Property8' cannot implement 'Interface.Property8' because it does not have matching return by reference. // class Class : Interface - Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.Property8", "Class.Property8", "reference").WithLocation(17, 15), - // (17,15): error CS8152: 'Class' does not implement interface member 'Interface.Property9'. 'Class.Property9' cannot implement 'Interface.Property9' because it does not return by value + Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.Property8", "Class.Property8").WithLocation(17, 15), + // (17,15): error CS8152: 'Class' does not implement interface member 'Interface.Property9'. 'Class.Property9' cannot implement 'Interface.Property9' because it does not have matching return by reference. // class Class : Interface - Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.Property9", "Class.Property9", "value").WithLocation(17, 15), + Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.Property9", "Class.Property9").WithLocation(17, 15), // (17,15): error CS0535: 'Class' does not implement interface member 'Interface.Property1' // class Class : Interface Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.Property1").WithLocation(17, 15)); @@ -2602,12 +2603,12 @@ class Class : Interface // (17,15): error CS0535: 'Class' does not implement interface member 'Interface.this[int, string, string, string].set' // class Class : Interface Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.this[int, string, string, string].set").WithLocation(17, 15), - // (17,15): error CS8086: 'Class' does not implement interface member 'Interface.this[string, int, int, int]'. 'Class.this[string, int, int, int]' cannot implement 'Interface.this[string, int, int, int]' because it does not return by reference. + // (17,15): error CS8152: 'Class' does not implement interface member 'Interface.this[string, int, int, int]'. 'Class.this[string, int, int, int]' cannot implement 'Interface.this[string, int, int, int]' because it does not have matching return by reference. // class Class : Interface - Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.this[string, int, int, int]", "Class.this[string, int, int, int]", "reference").WithLocation(17, 15), - // (17,15): error CS8086: 'Class' does not implement interface member 'Interface.this[string, int, int, string]'. 'Class.this[string, int, int, string]' cannot implement 'Interface.this[string, int, int, string]' because it does not return by value. + Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.this[string, int, int, int]", "Class.this[string, int, int, int]").WithLocation(17, 15), + // (17,15): error CS8152: 'Class' does not implement interface member 'Interface.this[string, int, int, string]'. 'Class.this[string, int, int, string]' cannot implement 'Interface.this[string, int, int, string]' because it does not have matching return by reference. // class Class : Interface - Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.this[string, int, int, string]", "Class.this[string, int, int, string]", "value").WithLocation(17, 15), + Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "Interface").WithArguments("Class", "Interface.this[string, int, int, string]", "Class.this[string, int, int, string]").WithLocation(17, 15), // (17,15): error CS0535: 'Class' does not implement interface member 'Interface.this[int, int, string, string].get' // class Class : Interface Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "Interface").WithArguments("Class", "Interface.this[int, int, string, string].get").WithLocation(17, 15), @@ -5453,8 +5454,9 @@ class Derived2 : Base2 }"; CreateCompilationWithMscorlib(text).VerifyDiagnostics( - // (14,26): error CS0663: 'Derived2' cannot define overloaded methods that differ only on ref and out - Diagnostic(ErrorCode.ERR_OverloadRefOut, "Method").WithArguments("Derived2")); + // (14,26): error CS0663: 'Derived2' cannot define an overloaded method that differs only on parameter modifiers 'ref' and 'out' + // public override void Method(int x, ref int y, out Exception z) { z = null; } + Diagnostic(ErrorCode.ERR_OverloadRefKind, "Method").WithArguments("Derived2", "method", "ref", "out").WithLocation(14, 26)); } [Fact] diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/InterfaceOverriddenOrHiddenMembersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/InterfaceOverriddenOrHiddenMembersTests.cs index e56756aa007d0..d1318bf2abe5a 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/InterfaceOverriddenOrHiddenMembersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/InterfaceOverriddenOrHiddenMembersTests.cs @@ -819,5 +819,558 @@ public interface Test { } }"; CreateCompilationWithMscorlib(source).VerifyDiagnostics(); } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingMethodWithRefReadOnlyParameter() + { + var code = @" +interface A +{ + void M(ref readonly int x); +} +interface B : A +{ + void M(ref readonly int x); +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (8,10): warning CS0108: 'B.M(ref readonly int)' hides inherited member 'A.M(ref readonly int)'. Use the new keyword if hiding was intended. + // void M(ref readonly int x); + Diagnostic(ErrorCode.WRN_NewRequired, "M").WithArguments("B.M(ref readonly int)", "A.M(ref readonly int)").WithLocation(8, 10)); + + var aMethod = comp.GetMember("A.M"); + var bMethod = comp.GetMember("B.M"); + + Assert.Empty(aMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aMethod.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aMethod, bMethod.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingMethodWithRefReadOnlyReturnType_RefReadOnly_RefReadOnly() + { + var code = @" +interface A +{ + ref readonly int M(); +} +interface B : A +{ + ref readonly int M(); +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (8,22): warning CS0108: 'B.M()' hides inherited member 'A.M()'. Use the new keyword if hiding was intended. + // ref readonly int M(); + Diagnostic(ErrorCode.WRN_NewRequired, "M").WithArguments("B.M()", "A.M()").WithLocation(8, 22)); + + var aMethod = comp.GetMember("A.M"); + var bMethod = comp.GetMember("B.M"); + + Assert.Empty(aMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aMethod.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aMethod, bMethod.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingMethodWithRefReadOnlyReturnType_Ref_RefReadOnly() + { + var code = @" +interface A +{ + ref int M(); +} +interface B : A +{ + ref readonly int M(); +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (8,22): warning CS0108: 'B.M()' hides inherited member 'A.M()'. Use the new keyword if hiding was intended. + // ref readonly int M(); + Diagnostic(ErrorCode.WRN_NewRequired, "M").WithArguments("B.M()", "A.M()").WithLocation(8, 22)); + + var aMethod = comp.GetMember("A.M"); + var bMethod = comp.GetMember("B.M"); + + Assert.Empty(aMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aMethod.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aMethod, bMethod.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingMethodWithRefReadOnlyReturnType_RefReadOnly_Ref() + { + var code = @" +interface A +{ + ref readonly int M(); +} +interface B : A +{ + ref int M(); +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (8,13): warning CS0108: 'B.M()' hides inherited member 'A.M()'. Use the new keyword if hiding was intended. + // ref readonly int M(); + Diagnostic(ErrorCode.WRN_NewRequired, "M").WithArguments("B.M()", "A.M()").WithLocation(8, 13)); + + var aMethod = comp.GetMember("A.M"); + var bMethod = comp.GetMember("B.M"); + + Assert.Empty(aMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aMethod.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aMethod, bMethod.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingPropertyWithRefReadOnlyReturnType_RefReadonly_RefReadonly() + { + var code = @" +interface A +{ + ref readonly int Property { get; } +} +interface B : A +{ + ref readonly int Property { get; } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (8,22): warning CS0108: 'B.Property' hides inherited member 'A.Property'. Use the new keyword if hiding was intended. + // ref readonly int Property { get; } + Diagnostic(ErrorCode.WRN_NewRequired, "Property").WithArguments("B.Property", "A.Property").WithLocation(8, 22)); + + var aProperty = comp.GetMember("A.Property"); + var bProperty = comp.GetMember("B.Property"); + + Assert.Empty(aProperty.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aProperty.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bProperty.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aProperty, bProperty.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingPropertyWithRefReadOnlyReturnType_RefReadonly_Ref() + { + var code = @" +interface A +{ + ref readonly int Property { get; } +} +interface B : A +{ + ref int Property { get; } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (8,13): warning CS0108: 'B.Property' hides inherited member 'A.Property'. Use the new keyword if hiding was intended. + // ref int Property { get; } + Diagnostic(ErrorCode.WRN_NewRequired, "Property").WithArguments("B.Property", "A.Property").WithLocation(8, 13)); + + var aProperty = comp.GetMember("A.Property"); + var bProperty = comp.GetMember("B.Property"); + + Assert.Empty(aProperty.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aProperty.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bProperty.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aProperty, bProperty.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingPropertyWithRefReadOnlyReturnType_Ref_RefReadonly() + { + var code = @" +interface A +{ + ref int Property { get; } +} +interface B : A +{ + ref readonly int Property { get; } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (8,22): warning CS0108: 'B.Property' hides inherited member 'A.Property'. Use the new keyword if hiding was intended. + // ref readonly int Property { get; } + Diagnostic(ErrorCode.WRN_NewRequired, "Property").WithArguments("B.Property", "A.Property").WithLocation(8, 22)); + + var aProperty = comp.GetMember("A.Property"); + var bProperty = comp.GetMember("B.Property"); + + Assert.Empty(aProperty.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aProperty.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bProperty.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aProperty, bProperty.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingMethodWithRefReadOnlyParameterAndNewKeyword() + { + var code = @" +interface A +{ + void M(ref readonly int x); +} +interface B : A +{ + new void M(ref readonly int x); +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics(); + + var aMethod = comp.GetMember("A.M"); + var bMethod = comp.GetMember("B.M"); + + Assert.Empty(aMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aMethod.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aMethod, bMethod.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingMethodWithRefReadOnlyReturnTypeAndNewKeyword() + { + var code = @" +interface A +{ + ref readonly int M(); +} +interface B : A +{ + new ref readonly int M(); +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics(); + + var aMethod = comp.GetMember("A.M"); + var bMethod = comp.GetMember("B.M"); + + Assert.Empty(aMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aMethod.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aMethod, bMethod.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingPropertyWithRefReadOnlyReturnTypeAndNewKeyword() + { + var code = @" +interface A +{ + ref readonly int Property { get ; } +} +interface B : A +{ + new ref readonly int Property { get; } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics(); + + var aProperty = comp.GetMember("A.Property"); + var bProperty = comp.GetMember("B.Property"); + + Assert.Empty(aProperty.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aProperty.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bProperty.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aProperty, bProperty.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void ImplementingMethodWithRefReadOnlyParameter() + { + var code = @" +interface A +{ + void M(ref readonly int x); +} +class B : A +{ + public void M(ref readonly int x) { } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics(); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void ImplementingMethodWithRefReadOnlyReturnType() + { + var code = @" +interface A +{ + ref readonly int M(); +} +class B : A +{ + protected int x = 0; + public ref readonly int M() { return ref x; } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics(); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void ImplementingPropertyWithRefReadOnlyReturnType() + { + var code = @" +interface A +{ + ref readonly int Property { get; } +} +class B : A +{ + protected int x = 0; + public ref readonly int Property { get { return ref x; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics(); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void ImplementingMethodWithDifferentParameterRefness() + { + var code = @" +interface A +{ + void M(ref readonly int x); +} +class B : A +{ + public void M(ref int x) { } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (6,11): error CS0535: 'B' does not implement interface member 'A.M(ref readonly int)' + // class B : A + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "A").WithArguments("B", "A.M(ref readonly int)").WithLocation(6, 11)); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void ImplementingRefReadOnlyMembersWillOverwriteTheCorrectSlot() + { + var text = @" +interface BaseInterface +{ + ref readonly int Method1(ref readonly int a); + ref readonly int Property1 { get; } + ref readonly int this[int a] { get; } +} + +class DerivedClass : BaseInterface +{ + protected int field; + public ref readonly int Method1(ref readonly int a) { return ref field; } + public ref readonly int Property1 { get { return ref field; } } + public ref readonly int this[int a] { get { return ref field; } } +}"; + + var comp = CreateCompilationWithMscorlib(text).VerifyDiagnostics(); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void MethodImplementationsShouldPreserveReadOnlyRefnessInParameters() + { + var text = @" +interface BaseInterface +{ + void Method1(ref int x); + void Method2(ref readonly int x); +} +class ChildClass : BaseInterface +{ + public void Method1(ref readonly int x) { } + public void Method2(ref int x) { } +}"; + + var comp = CreateCompilationWithMscorlib(text).VerifyDiagnostics( + // (7,20): error CS0535: 'ChildClass' does not implement interface member 'BaseInterface.Method2(ref readonly int)' + // class ChildClass : BaseInterface + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "BaseInterface").WithArguments("ChildClass", "BaseInterface.Method2(ref readonly int)").WithLocation(7, 20), + // (7,20): error CS0535: 'ChildClass' does not implement interface member 'BaseInterface.Method1(ref int)' + // class ChildClass : BaseInterface + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "BaseInterface").WithArguments("ChildClass", "BaseInterface.Method1(ref int)").WithLocation(7, 20)); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void MethodImplementationsShouldPreserveReadOnlyRefnessInReturnTypes() + { + var text = @" +interface BaseInterface +{ + ref int Method1(); + ref readonly int Method2(); +} +class ChildClass : BaseInterface +{ + protected int x = 0 ; + public ref readonly int Method1() { return ref x; } + public ref int Method2() { return ref x; } +}"; + + var comp = CreateCompilationWithMscorlib(text).VerifyDiagnostics( + // (7,20): error CS8152: 'ChildClass' does not implement interface member 'BaseInterface.Method2()'. 'ChildClass.Method2()' cannot implement 'BaseInterface.Method2()' because it does not have matching return by reference. + // class ChildClass : BaseInterface + Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "BaseInterface").WithArguments("ChildClass", "BaseInterface.Method2()", "ChildClass.Method2()").WithLocation(7, 20), + // (7,20): error CS8152: 'ChildClass' does not implement interface member 'BaseInterface.Method1()'. 'ChildClass.Method1()' cannot implement 'BaseInterface.Method1()' because it does not have matching return by reference. + // class ChildClass : BaseInterface + Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "BaseInterface").WithArguments("ChildClass", "BaseInterface.Method1()", "ChildClass.Method1()").WithLocation(7, 20)); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void PropertyImplementationsShouldPreserveReadOnlyRefnessInReturnTypes() + { + var code = @" +interface A +{ + ref int Property1 { get; } + ref readonly int Property2 { get; } +} +class B : A +{ + protected int x = 0; + public ref readonly int Property1 { get { return ref x; } } + public ref int Property2 { get { return ref x; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (7,11): error CS8152: 'B' does not implement interface member 'A.Property2'. 'B.Property2' cannot implement 'A.Property2' because it does not have matching return by reference. + // class B : A + Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "A").WithArguments("B", "A.Property2", "B.Property2").WithLocation(7, 11), + // (7,11): error CS8152: 'B' does not implement interface member 'A.Property1'. 'B.Property1' cannot implement 'A.Property1' because it does not have matching return by reference. + // class B : A + Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "A").WithArguments("B", "A.Property1", "B.Property1").WithLocation(7, 11)); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void IndexerImplementationsShouldPreserveReadOnlyRefnessInReturnTypes_Ref_RefReadOnly() + { + var code = @" +interface A +{ + ref int this[int p] { get; } +} +class B : A +{ + protected int x = 0; + public ref readonly int this[int p] { get { return ref x; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (6,11): error CS8152: 'B' does not implement interface member 'A.this[int]'. 'B.this[int]' cannot implement 'A.this[int]' because it does not have matching return by reference. + // class B : A + Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "A").WithArguments("B", "A.this[int]", "B.this[int]").WithLocation(6, 11)); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void IndexerImplementationsShouldPreserveReadOnlyRefnessInReturnTypes_RefReadOnly_Ref() + { + var code = @" +interface A +{ + ref readonly int this[int p] { get; } +} +class B : A +{ + protected int x = 0; + public ref int this[int p] { get { return ref x; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (6,11): error CS8152: 'B' does not implement interface member 'A.this[int]'. 'B.this[int]' cannot implement 'A.this[int]' because it does not have matching return by reference. + // class B : A + Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn, "A").WithArguments("B", "A.this[int]", "B.this[int]").WithLocation(6, 11)); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void IndexerImplementationsShouldPreserveReadOnlyRefnessInIndexes_Valid() + { + var code = @" +interface A +{ + int this[ref readonly int p] { get; } +} +class B : A +{ + public int this[ref readonly int p] { get { return p; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics(); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void IndexerImplementationsShouldPreserveReadOnlyRefnessInIndexes_Source() + { + var code = @" +interface A +{ + int this[ref readonly int p] { get; } +} +class B : A +{ + public int this[int p] { get { return p; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (6,11): error CS0535: 'B' does not implement interface member 'A.this[ref readonly int]' + // class B : A + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "A").WithArguments("B", "A.this[ref readonly int]").WithLocation(6, 11)); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void IndexerImplementationsShouldPreserveReadOnlyRefnessInIndexes_Destination() + { + var code = @" +interface A +{ + int this[int p] { get; } +} +class B : A +{ + public int this[ref readonly int p] { get { return p; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (6,11): error CS0535: 'B' does not implement interface member 'A.this[int]' + // class B : A + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "A").WithArguments("B", "A.this[int]").WithLocation(6, 11)); + } } } diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/OverriddenOrHiddenMembersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/OverriddenOrHiddenMembersTests.cs index 1bb37ca69cf2e..c5e9c75c8e878 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/OverriddenOrHiddenMembersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/OverriddenOrHiddenMembersTests.cs @@ -3983,5 +3983,633 @@ public class Required : ValidatorBase } #endregion - } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingMethodWithRefReadOnlyParameter() + { + var code = @" +class A +{ + public void M(ref readonly int x) { } +} +class B : A +{ + public void M(ref readonly int x) { } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (8,17): warning CS0108: 'B.M(ref readonly int)' hides inherited member 'A.M(ref readonly int)'. Use the new keyword if hiding was intended. + // public void M(ref readonly int x) { } + Diagnostic(ErrorCode.WRN_NewRequired, "M").WithArguments("B.M(ref readonly int)", "A.M(ref readonly int)").WithLocation(8, 17)); + + var aMethod = comp.GetMember("A.M"); + var bMethod = comp.GetMember("B.M"); + + Assert.Empty(aMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aMethod.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aMethod, bMethod.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingMethodWithRefReadOnlyReturnType_RefReadOnly_RefReadOnly() + { + var code = @" +class A +{ + protected int x = 0; + public ref readonly int M() { return ref x; } +} +class B : A +{ + public ref readonly int M() { return ref x; } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (9,29): warning CS0108: 'B.M()' hides inherited member 'A.M()'. Use the new keyword if hiding was intended. + // public ref readonly int M() { return ref x; } + Diagnostic(ErrorCode.WRN_NewRequired, "M").WithArguments("B.M()", "A.M()").WithLocation(9, 29)); + + var aMethod = comp.GetMember("A.M"); + var bMethod = comp.GetMember("B.M"); + + Assert.Empty(aMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aMethod.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aMethod, bMethod.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingMethodWithRefReadOnlyReturnType_Ref_RefReadOnly() + { + var code = @" +class A +{ + protected int x = 0; + public ref int M() { return ref x; } +} +class B : A +{ + public ref readonly int M() { return ref x; } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (9,29): warning CS0108: 'B.M()' hides inherited member 'A.M()'. Use the new keyword if hiding was intended. + // public ref readonly int M() { return ref x; } + Diagnostic(ErrorCode.WRN_NewRequired, "M").WithArguments("B.M()", "A.M()").WithLocation(9, 29)); + + var aMethod = comp.GetMember("A.M"); + var bMethod = comp.GetMember("B.M"); + + Assert.Empty(aMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aMethod.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aMethod, bMethod.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingMethodWithRefReadOnlyReturnType_RefReadOnly_Ref() + { + var code = @" +class A +{ + protected int x = 0; + public ref readonly int M() { return ref x; } +} +class B : A +{ + public ref int M() { return ref x; } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (9,20): warning CS0108: 'B.M()' hides inherited member 'A.M()'. Use the new keyword if hiding was intended. + // public ref int M() { return ref x; } + Diagnostic(ErrorCode.WRN_NewRequired, "M").WithArguments("B.M()", "A.M()").WithLocation(9, 20)); + + var aMethod = comp.GetMember("A.M"); + var bMethod = comp.GetMember("B.M"); + + Assert.Empty(aMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aMethod.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aMethod, bMethod.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingPropertyWithRefReadOnlyReturnType_RefReadOnly_RefReadOnly() + { + var code = @" +class A +{ + protected int x = 0; + public ref readonly int Property { get { return ref x; } } +} +class B : A +{ + public ref readonly int Property { get { return ref x; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (9,29): warning CS0108: 'B.Property' hides inherited member 'A.Property'. Use the new keyword if hiding was intended. + // public ref readonly int Property { get { return ref x; } } + Diagnostic(ErrorCode.WRN_NewRequired, "Property").WithArguments("B.Property", "A.Property").WithLocation(9, 29)); + + var aProperty = comp.GetMember("A.Property"); + var bProperty = comp.GetMember("B.Property"); + + Assert.Empty(aProperty.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aProperty.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bProperty.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aProperty, bProperty.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingPropertyWithRefReadOnlyReturnType_RefReadOnly_Ref() + { + var code = @" +class A +{ + protected int x = 0; + public ref readonly int Property { get { return ref x; } } +} +class B : A +{ + public ref int Property { get { return ref x; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (9,20): warning CS0108: 'B.Property' hides inherited member 'A.Property'. Use the new keyword if hiding was intended. + // public ref int Property { get { return ref x; } } + Diagnostic(ErrorCode.WRN_NewRequired, "Property").WithArguments("B.Property", "A.Property").WithLocation(9, 20)); + + var aProperty = comp.GetMember("A.Property"); + var bProperty = comp.GetMember("B.Property"); + + Assert.Empty(aProperty.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aProperty.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bProperty.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aProperty, bProperty.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingPropertyWithRefReadOnlyReturnType_Ref_RefReadOnly() + { + var code = @" +class A +{ + protected int x = 0; + public ref int Property { get { return ref x; } } +} +class B : A +{ + public ref readonly int Property { get { return ref x; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (9,29): warning CS0108: 'B.Property' hides inherited member 'A.Property'. Use the new keyword if hiding was intended. + // public ref readonly int Property { get { return ref x; } } + Diagnostic(ErrorCode.WRN_NewRequired, "Property").WithArguments("B.Property", "A.Property").WithLocation(9, 29)); + + var aProperty = comp.GetMember("A.Property"); + var bProperty = comp.GetMember("B.Property"); + + Assert.Empty(aProperty.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aProperty.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bProperty.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aProperty, bProperty.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingMethodWithRefReadOnlyParameterAndNewKeyword() + { + var code = @" +class A +{ + public void M(ref readonly int x) { } +} +class B : A +{ + public new void M(ref readonly int x) { } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics(); + + var aMethod = comp.GetMember("A.M"); + var bMethod = comp.GetMember("B.M"); + + Assert.Empty(aMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aMethod.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aMethod, bMethod.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingMethodWithRefReadOnlyReturnTypeAndNewKeyword() + { + var code = @" +class A +{ + protected int x = 0; + public ref readonly int M() { return ref x; } +} +class B : A +{ + public new ref readonly int M() { return ref x; } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics(); + + var aMethod = comp.GetMember("A.M"); + var bMethod = comp.GetMember("B.M"); + + Assert.Empty(aMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aMethod.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aMethod, bMethod.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void HidingPropertyWithRefReadOnlyReturnTypeAndNewKeyword() + { + var code = @" +class A +{ + protected int x = 0; + public ref readonly int Property { get { return ref x; } } +} +class B : A +{ + public new ref readonly int Property { get { return ref x; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics(); + + var aProperty = comp.GetMember("A.Property"); + var bProperty = comp.GetMember("B.Property"); + + Assert.Empty(aProperty.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aProperty.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bProperty.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Equal(aProperty, bProperty.OverriddenOrHiddenMembers.HiddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void OverridingMethodWithRefReadOnlyParameter() + { + var code = @" +class A +{ + public virtual void M(ref readonly int x) { } +} +class B : A +{ + public override void M(ref readonly int x) { } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics(); + + var aMethod = comp.GetMember("A.M"); + var bMethod = comp.GetMember("B.M"); + + Assert.Empty(aMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aMethod.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Equal(aMethod, bMethod.OverriddenOrHiddenMembers.OverriddenMembers.Single()); + Assert.Empty(bMethod.OverriddenOrHiddenMembers.HiddenMembers); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void OverridingMethodWithRefReadOnlyReturnType() + { + var code = @" +class A +{ + protected int x = 0; + public virtual ref readonly int M() { return ref x; } +} +class B : A +{ + public override ref readonly int M() { return ref x; } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics(); + + var aMethod = comp.GetMember("A.M"); + var bMethod = comp.GetMember("B.M"); + + Assert.Empty(aMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aMethod.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Equal(aMethod, bMethod.OverriddenOrHiddenMembers.OverriddenMembers.Single()); + Assert.Empty(bMethod.OverriddenOrHiddenMembers.HiddenMembers); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void OverridingPropertyWithRefReadOnlyReturnType() + { + var code = @" +class A +{ + protected int x = 0; + public virtual ref readonly int Property { get { return ref x; } } +} +class B : A +{ + public override ref readonly int Property { get { return ref x; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics(); + + var aProperty = comp.GetMember("A.Property"); + var bProperty = comp.GetMember("B.Property"); + + Assert.Empty(aProperty.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aProperty.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Equal(aProperty, bProperty.OverriddenOrHiddenMembers.OverriddenMembers.Single()); + Assert.Empty(bProperty.OverriddenOrHiddenMembers.HiddenMembers); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void DeclaringMethodWithDifferentParameterRefness() + { + var code = @" +class A +{ + public void M(ref readonly int x) { } +} +class B : A +{ + public void M(ref int x) { } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics(); + + var aMethod = comp.GetMember("A.M"); + var bMethod = comp.GetMember("B.M"); + + Assert.NotEqual(aMethod, bMethod); + + Assert.Empty(aMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(aMethod.OverriddenOrHiddenMembers.HiddenMembers); + + Assert.Empty(bMethod.OverriddenOrHiddenMembers.OverriddenMembers); + Assert.Empty(bMethod.OverriddenOrHiddenMembers.HiddenMembers); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void OverriddingRefReadOnlyMembersWillOverwriteTheCorrectSlot() + { + var text = @" +class BaseClass +{ + protected int field; + public virtual ref readonly int Method1(ref readonly BaseClass a) { return ref field; } + public virtual ref readonly int Property1 { get { return ref field; } } + public virtual ref readonly int this[int a] { get { return ref field; } } +} + +class DerivedClass : BaseClass +{ + public override ref readonly int Method1(ref readonly BaseClass a) { return ref field; } + public override ref readonly int Property1 { get { return ref field; } } + public override ref readonly int this[int a] { get { return ref field; } } +}"; + + var comp = CreateCompilationWithMscorlib(text).VerifyDiagnostics(); + + var baseMethod = comp.GetMember("BaseClass.Method1"); + var baseProperty = comp.GetMember("BaseClass.Property1"); + var baseIndexer = comp.GetMember("BaseClass.this[]"); + + var derivedMethod = comp.GetMember("DerivedClass.Method1"); + var derivedProperty = comp.GetMember("DerivedClass.Property1"); + var derivedIndexer = comp.GetMember("DerivedClass.this[]"); + + Assert.Empty(baseMethod.OverriddenOrHiddenMembers.HiddenMembers); + Assert.Empty(baseMethod.OverriddenOrHiddenMembers.OverriddenMembers); + + Assert.Empty(baseProperty.OverriddenOrHiddenMembers.HiddenMembers); + Assert.Empty(baseProperty.OverriddenOrHiddenMembers.OverriddenMembers); + + Assert.Empty(baseIndexer.OverriddenOrHiddenMembers.HiddenMembers); + Assert.Empty(baseIndexer.OverriddenOrHiddenMembers.OverriddenMembers); + + Assert.Empty(derivedMethod.OverriddenOrHiddenMembers.HiddenMembers); + Assert.Equal(baseMethod, derivedMethod.OverriddenOrHiddenMembers.OverriddenMembers.Single()); + + Assert.Empty(derivedProperty.OverriddenOrHiddenMembers.HiddenMembers); + Assert.Equal(baseProperty, derivedProperty.OverriddenOrHiddenMembers.OverriddenMembers.Single()); + + Assert.Empty(derivedIndexer.OverriddenOrHiddenMembers.HiddenMembers); + Assert.Equal(baseIndexer, derivedIndexer.OverriddenOrHiddenMembers.OverriddenMembers.Single()); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void MethodOverloadsShouldPreserveReadOnlyRefnessInParameters() + { + var text = @" +abstract class BaseClass +{ + public virtual void Method1(ref int x) { } + public virtual void Method2(ref readonly int x) { } +} +class ChildClass : BaseClass +{ + public override void Method1(ref readonly int x) { } + public override void Method2(ref int x) { } +}"; + + var comp = CreateCompilationWithMscorlib(text).VerifyDiagnostics( + // (10,26): error CS0115: 'ChildClass.Method2(ref int)': no suitable method found to override + // public override void Method2(ref int x) { } + Diagnostic(ErrorCode.ERR_OverrideNotExpected, "Method2").WithArguments("ChildClass.Method2(ref int)").WithLocation(10, 26), + // (9,26): error CS0115: 'ChildClass.Method1(ref readonly int)': no suitable method found to override + // public override void Method1(ref readonly int x) { } + Diagnostic(ErrorCode.ERR_OverrideNotExpected, "Method1").WithArguments("ChildClass.Method1(ref readonly int)").WithLocation(9, 26)); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void MethodOverloadsShouldPreserveReadOnlyRefnessInReturnTypes() + { + var text = @" +abstract class BaseClass +{ + protected int x = 0 ; + public virtual ref int Method1() { return ref x; } + public virtual ref readonly int Method2() { return ref x; } +} +class ChildClass : BaseClass +{ + public override ref readonly int Method1() { return ref x; } + public override ref int Method2() { return ref x; } +}"; + + var comp = CreateCompilationWithMscorlib(text).VerifyDiagnostics( + // (11,29): error CS8148: 'ChildClass.Method2()' must match by reference return of overridden member 'BaseClass.Method2()' + // public override ref int Method2() { return ref x; } + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method2").WithArguments("ChildClass.Method2()", "BaseClass.Method2()").WithLocation(11, 29), + // (10,38): error CS8148: 'ChildClass.Method1()' must match by reference return of overridden member 'BaseClass.Method1()' + // public override ref readonly int Method1() { return ref x; } + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method1").WithArguments("ChildClass.Method1()", "BaseClass.Method1()").WithLocation(10, 38)); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void PropertyOverloadsShouldPreserveReadOnlyRefnessInReturnTypes() + { + var code = @" +class A +{ + protected int x = 0; + public virtual ref int Property1 { get { return ref x; } } + public virtual ref readonly int Property2 { get { return ref x; } } +} +class B : A +{ + public override ref readonly int Property1 { get { return ref x; } } + public override ref int Property2 { get { return ref x; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (11,29): error CS8148: 'B.Property2' must match by reference return of overridden member 'A.Property2' + // public override ref int Property2 { get { return ref x; } } + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Property2").WithArguments("B.Property2", "A.Property2").WithLocation(11, 29), + // (10,38): error CS8148: 'B.Property1' must match by reference return of overridden member 'A.Property1' + // public override ref readonly int Property1 { get { return ref x; } } + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Property1").WithArguments("B.Property1", "A.Property1").WithLocation(10, 38)); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void IndexerOverloadsShouldPreserveReadOnlyRefnessInReturnTypes_Ref_RefReadOnly() + { + var code = @" +class A +{ + protected int x = 0; + public virtual ref int this[int p] { get { return ref x; } } } +class B : A +{ + public override ref readonly int this[int p] { get { return ref x; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (9,38): error CS8148: 'B.this[int]' must match by reference return of overridden member 'A.this[int]' + // public override ref readonly int this[int p] { get { return ref x; } } + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "this").WithArguments("B.this[int]", "A.this[int]").WithLocation(9, 38)); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void IndexerOverloadsShouldPreserveReadOnlyRefnessInReturnTypes_RefReadOnly_Ref() + { + var code = @" +class A +{ + protected int x = 0; + public virtual ref readonly int this[int p] { get { return ref x; } } +} +class B : A +{ + public override ref int this[int p] { get { return ref x; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (9,29): error CS8148: 'B.this[int]' must match by reference return of overridden member 'A.this[int]' + // public override ref int this[int p] { get { return ref x; } } + Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "this").WithArguments("B.this[int]", "A.this[int]").WithLocation(9, 29)); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void IndexerOverloadsShouldPreserveReadOnlyRefnessInIndexes_Valid() + { + var code = @" +abstract class A +{ + public abstract int this[ref readonly int p] { get; } +} +class B : A +{ + public override int this[ref readonly int p] { get { return p; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics(); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void IndexerOverloadsShouldPreserveReadOnlyRefnessInIndexes_Source() + { + var code = @" +abstract class A +{ + public abstract int this[ref readonly int p] { get; } +} +class B : A +{ + public override int this[int p] { get { return p; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (8,25): error CS0115: 'B.this[int]': no suitable method found to override + // public override int this[int p] { get { return p; } } + Diagnostic(ErrorCode.ERR_OverrideNotExpected, "this").WithArguments("B.this[int]").WithLocation(8, 25), + // (6,7): error CS0534: 'B' does not implement inherited abstract member 'A.this[ref readonly int].get' + // class B : A + Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "B").WithArguments("B", "A.this[ref readonly int].get").WithLocation(6, 7)); + } + + [Fact] + [CompilerTrait(CompilerFeature.ReadonlyReferences)] + public void IndexerOverloadsShouldPreserveReadOnlyRefnessInIndexes_Destination() + { + var code = @" +abstract class A +{ + public abstract int this[int p] { get; } +} +class B : A +{ + public override int this[ref readonly int p] { get { return p; } } +}"; + + var comp = CreateCompilationWithMscorlib(code).VerifyDiagnostics( + // (8,25): error CS0115: 'B.this[ref readonly int]': no suitable method found to override + // public override int this[ref readonly int p] { get { return p; } } + Diagnostic(ErrorCode.ERR_OverrideNotExpected, "this").WithArguments("B.this[ref readonly int]").WithLocation(8, 25), + // (6,7): error CS0534: 'B' does not implement inherited abstract member 'A.this[int].get' + // class B : A + Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "B").WithArguments("B", "A.this[int].get").WithLocation(6, 7)); + } + } +} \ No newline at end of file diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs index 33abfe7311271..88f378e714ed4 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/SymbolErrorTests.cs @@ -11348,24 +11348,27 @@ public int RetInt(byte b, int k) var comp = CreateCompilationWithMscorlib(text); comp.VerifyDiagnostics( - // (7,14): error CS0663: 'NS.IFoo' cannot define overloaded methods that differ only on ref and out - Diagnostic(ErrorCode.ERR_OverloadRefOut, "M").WithArguments("NS.IFoo"), - // (24,20): error CS0663: 'NS.CFoo' cannot define overloaded methods that differ only on ref and out - Diagnostic(ErrorCode.ERR_OverloadRefOut, "RetInt").WithArguments("NS.CFoo"), - // (16,18): error CS0663: 'NS.CFoo.SFoo' cannot define overloaded methods that differ only on ref and out - Diagnostic(ErrorCode.ERR_OverloadRefOut, "M").WithArguments("NS.CFoo.SFoo"), + // (7,14): error CS0663: 'IFoo' cannot define an overloaded method that differ only on parameter modifiers 'out' and 'ref' + // void M(out T t); + Diagnostic(ErrorCode.ERR_OverloadRefKind, "M").WithArguments("NS.IFoo", "method", "out", "ref").WithLocation(7, 14), + // (24,20): error CS0663: 'CFoo' cannot define an overloaded method that differ only on parameter modifiers 'ref' and 'out' + // public int RetInt(byte b, ref int j) + Diagnostic(ErrorCode.ERR_OverloadRefKind, "RetInt").WithArguments("NS.CFoo", "method", "ref", "out").WithLocation(24, 20), + // (16,18): error CS0663: 'CFoo.SFoo' cannot define an overloaded method that differ only on parameter modifiers 'out' and 'ref' + // void M(out T t) { } + Diagnostic(ErrorCode.ERR_OverloadRefKind, "M").WithArguments("NS.CFoo.SFoo", "method", "out", "ref").WithLocation(16, 18), // Dev10 stops after reporting the overload problems. However, it produces the errors below once those problems are fixed. // (21,20): error CS0269: Use of unassigned out parameter 'i' - Diagnostic(ErrorCode.ERR_UseDefViolationOut, "i").WithArguments("i"), + // return i; + Diagnostic(ErrorCode.ERR_UseDefViolationOut, "i").WithArguments("i").WithLocation(21, 20), // (21,13): error CS0177: The out parameter 'i' must be assigned to before control leaves the current method - Diagnostic(ErrorCode.ERR_ParamUnassigned, "return i;").WithArguments("i"), + // return i; + Diagnostic(ErrorCode.ERR_ParamUnassigned, "return i;").WithArguments("i").WithLocation(21, 13), // (16,18): error CS0177: The out parameter 't' must be assigned to before control leaves the current method - Diagnostic(ErrorCode.ERR_ParamUnassigned, "M").WithArguments("t")); - - var ns = comp.SourceModule.GlobalNamespace.GetMembers("NS").Single() as NamespaceSymbol; - // TODO... + // void M(out T t) { } + Diagnostic(ErrorCode.ERR_ParamUnassigned, "M").WithArguments("t").WithLocation(16, 18)); } [Fact] @@ -13805,8 +13808,9 @@ public MyClass(out int num) }"; CreateCompilationWithMscorlib(text).VerifyDiagnostics( - // (8,17): error CS0851: Cannot define overloaded constructor 'TestNamespace.MyClass' because it differs from another constructor only on ref and out - Diagnostic(ErrorCode.ERR_OverloadRefOutCtor, "MyClass").WithArguments("TestNamespace.MyClass")); + // (8,17): error CS0663: 'MyClass' cannot define an overloaded constructor that differs only on parameter modifiers 'out' and 'ref' + // public MyClass(out int num) + Diagnostic(ErrorCode.ERR_OverloadRefKind, "MyClass").WithArguments("TestNamespace.MyClass", "constructor", "out", "ref").WithLocation(8, 17)); } [Fact]