未验证 提交 6ddf37ae 编写于 作者: R Rikki Gibson 提交者: GitHub

User-defined operator checks should ignore differences in tuple member names (#30774)

* Add test for tuple operator increment

* Ignore tuple names when comparing return types to parameter types in increment/decrement operators

* Add test for tuple identity conversion operator

* Ignore tuple names when comparing conversion operator parameter and return types

* Add test for tuple conversion to base type

* Ignore tuple names when determining whether parameter or return type contains a conversion operator

* Add test for tuple binary operator

* Filter out type conflict warnings
上级 603dca70
......@@ -292,7 +292,9 @@ private void CheckUserDefinedConversionSignature(DiagnosticBag diagnostics)
// SPEC: * S0 and T0 are different types:
if ((ContainingType.SpecialType == SpecialType.System_Nullable_T) ? source == target : source0 == target0)
if ((ContainingType.SpecialType == SpecialType.System_Nullable_T)
? source.Equals(target, TypeCompareKind.IgnoreTupleNames)
: source0.Equals(target0, TypeCompareKind.IgnoreTupleNames))
{
// CS0555: User-defined operator cannot take an object of the enclosing type
// and convert to an object of the enclosing type
......@@ -371,7 +373,7 @@ private void CheckUserDefinedConversionSignature(DiagnosticBag diagnostics)
TypeSymbol same;
TypeSymbol different;
if (source0 == this.ContainingType)
if (source0.Equals(this.ContainingType, TypeCompareKind.IgnoreTupleNames))
{
same = source;
different = target;
......@@ -492,7 +494,7 @@ private void CheckIncrementDecrementSignature(DiagnosticBag diagnostics)
// CS0559: The parameter type for ++ or -- operator must be the containing type
diagnostics.Add(ErrorCode.ERR_BadIncDecSignature, this.Locations[0]);
}
else if (!this.ReturnType.TypeSymbol.EffectiveTypeNoUseSiteDiagnostics.IsEqualToOrDerivedFrom(parameterType, TypeCompareKind.ConsiderEverything, useSiteDiagnostics: ref useSiteDiagnostics))
else if (!this.ReturnType.TypeSymbol.EffectiveTypeNoUseSiteDiagnostics.IsEqualToOrDerivedFrom(parameterType, TypeCompareKind.IgnoreTupleNames, useSiteDiagnostics: ref useSiteDiagnostics))
{
// CS0448: The return type for ++ or -- operator must match the parameter type
// or be derived from the parameter type
......
......@@ -5814,6 +5814,84 @@ static void Main()
CreateCompilation(text).VerifyDiagnostics(Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "b++").WithArguments("A", "B"));
}
[Fact, WorkItem(30668, "https://github.com/dotnet/roslyn/issues/30668")]
public void TestTupleOperatorIncrement()
{
var text = @"
namespace System
{
struct ValueTuple<T1, T2>
{
public static (T1 fst, T2 snd) operator ++((T1 one, T2 two) tuple)
{
return tuple;
}
}
}
";
CreateCompilation(text).VerifyDiagnostics();
}
[Fact, WorkItem(30668, "https://github.com/dotnet/roslyn/issues/30668")]
public void TestTupleOperatorConvert()
{
var text = @"
namespace System
{
struct ValueTuple<T1, T2>
{
public static explicit operator (T1 fst, T2 snd)((T1 one, T2 two) s)
{
return s;
}
}
}
";
CreateCompilation(text).VerifyDiagnostics(
// (6,41): error CS0555: User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type
// public static explicit operator (T1 fst, T2 snd)((T1 one, T2 two) s)
Diagnostic(ErrorCode.ERR_IdentityConversion, "(T1 fst, T2 snd)").WithLocation(6, 41));
}
[Fact, WorkItem(30668, "https://github.com/dotnet/roslyn/issues/30668")]
public void TestTupleOperatorConvertToBaseType()
{
var text = @"
namespace System
{
struct ValueTuple<T1, T2>
{
public static explicit operator ValueType(ValueTuple<T1, T2> s)
{
return s;
}
}
}
";
CreateCompilation(text).GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error).Verify(
// (6,41): error CS0553: 'ValueTuple<T1, T2>.explicit operator ValueType((T1, T2))': user-defined conversions to or from a base class are not allowed
// public static explicit operator ValueType(ValueTuple<T1, T2> s)
Diagnostic(ErrorCode.ERR_ConversionWithBase, "ValueType").WithArguments("System.ValueTuple<T1, T2>.explicit operator System.ValueType((T1, T2))").WithLocation(6, 41));
}
[Fact, WorkItem(30668, "https://github.com/dotnet/roslyn/issues/30668")]
public void TestTupleBinaryOperator()
{
var text = @"
namespace System
{
struct ValueTuple<T1, T2>
{
public static ValueTuple<T1, T2> operator +((T1 fst, T2 snd) s1, (T1 one, T2 two) s2)
{
return s1;
}
}
}
";
CreateCompilation(text).GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error).Verify();
}
[WorkItem(543431, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543431")]
[Fact]
public void TestEqualityOperator_DelegateTypes_01()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册