Closed jcouv closed 6 years ago
[x] Test langver ( TestCSharp7_2 )
[x] Test different cardinalities of tuples ( TestTupleLiteralsWithDifferentCardinalities, TestTuplesWithDifferentCardinalities, TestNestedTuplesWithDifferentCardinalities)
[x] Nullable tuple to nullable tuple ( TestEqualOnNullableVsNullableTuples, TestNotEqualOnNullableVsNullableTuples)
[x] Nullable tuple to non-nullable tuple ( TestOnNullableVsNonNullableTuples , TestOnNullableVsNonNullableTuples3)
[x] Verify evaluation order ( TestEvaluationOrderOnTupleLiteral, TestEvaluationOrderOnTupleType, and other tests called "EvaluationOrder" should cover all the sub-bullets below)
(M(), ..) == (M(), ..)
, then M()
is invoked as many times as referenced==
, if the first element-wise comparison succeeds, we should continue to the second ( TestEvaluationOrderOnTupleLiteral )!=
==
on tuple results in ==
on elements (and conversely for !=
)bool
on the result of element-wise comparisonop_True
operator on the result of element-wise comparison[x] Verify converted types and element names in semantic model (various tests checking "ConvertedType")
[x] Appropriate warnings should be reported for element names mismatch, including nested cases ( TestElementNames )
[x] Behavior when ValueTuple
type is missing ( TestWithoutValueTuple )
[ ] Check that GetConstantValue
returns nothing on tuple, but returns something on a constant element ( TestSimpleEqualOnTypelessTupleLiteral)
[x] Check GetTypeInfo
on both operands (expressions and literals) and the elements (tests with "GetTypeInfo")
[x] Get GetDeclaredSymbol
on a tuple literal involved in tuple comparison (tests with "GetDeclaredSymbol")
[ ] Check unassigned usage of element in tuple comparison ( TestDefiniteAssignment)
[ ] Check WrittenInside
, AssignedInside
, etc APIs from region analysis ( AnalysisOfTupleEquality)
[ ] Test with any generic element (since no ==
can be declared, maybe falls back to object) ( TestGenericElement)
[x] Block in expression tree (TestInExpressionTree)
[ ] Test ref returning APIs as elements ((refReturningFoo(), refReturningProperty) == (1, 2)
)
nameof((..) == (...))
(TestRefReturningElements)
[ ] Show IL for checked
and unchecked
(TestChecked, TestUnchecked)
checked/unchecked
context affects: ((byte)0xFF + (byte)0xFF, ....) == (...)
[ ] Try to pass the comparison as ref
or out
argument (it's just an RValue) (TestAsRefOrOutArgument)
[ ] Use pointers as elements (should fail because pointers not allowed as type arguments) (TestWithPointer)
[ ] Test (M(out var x), x) == (1, 2)
(works) and (x, M(out var x)) == (1, 2)
(error) (TestDefiniteAssignment2)
[ ] Test anonymous types as elements ( TestWithAnonymousTypes, TestWithAnonymousTypes2)
[ ] Test in a query (in where
condition) (TestInQuery)
[x] Test that user-defined ==
on ValueTuple
is ignored ( TestTupleEqualityPreferredOverCustomOperator )
[x] Test that comparison on dynamic
results in dynamic invocation of ==
. It will succeed at runtime if there is an operator, and will fail at runtime if there is not operator== on the types involved. ( TestNonBoolComparisonResult_WithTrueFalseOperators for success case, TestDynamic_WithBadType for failure case)
[x] Test that conversions to tuple and Deconstruct
methods do not play a role (goes to resolution) ( TestEqualityOfTypeConvertingToTuple, TestComparisonWithDeconstruction )
[x] Test special comparisons null
to null
, null
to default
, default
to default
,
[x] Test element-wise comparison involving expressions that don't have a type (like lambdas or method groups, null
, typeless tuples, ) (TestFailedInference )
NormalizeWhitespaces
UpgradeProject
offered (Julien verified manually, see screencap below)([|a:|] a, 1) == ...
(the "a:" should be offered to be simplified) (Julien verified manually, see screencap below)truthiness
S?
compared to null
and null
compared to null
Tagging @AlekseyTs to do one pass of checking the marks based on tests names I provided. Thanks
UpgradeProject:
Highlighting:
No Extract Local offered when tuple is typeless (correct), but Extract Method is offered (incorrect):
Extract Local produces code with a name mismatch warning:
Renaming of expression in tuple works:
Redundant tuple element name is offered to be simplified:
@AlekseyTs Tuple equality is blocked on making progress on checking test plan.
@AlekseyTs I've added most of the remaining tests in PR https://github.com/dotnet/roslyn/pull/25486 before the feature was merged back to dev15.7.x branch. I've update the speclet as discussed. The remaining known issues (like struct this and optimization for always/never null) are tracked in individual issues.
I'll go ahead and close this umbrella issue.
Championed issue: https://github.com/dotnet/csharplang/issues/190
Various scenarios:
if (tuple1 == (1, 2)) ...
if (nestedTuple == ...) ...
if (nullableT1 == t2) ...
if (nullableT1 == nullableT2) ...
Open issues and test ideas:
this
(issue https://github.com/dotnet/roslyn/issues/25488, PR https://github.com/dotnet/roslyn/pull/25390)merge-fixups
(PR https://github.com/dotnet/roslyn/pull/25486)t8.Rest
)? (no, remains disallowed)block EnC (https://github.com/dotnet/roslyn/pull/25402)(default, default)
default
in comparison (https://github.com/dotnet/roslyn/pull/25327)==
,&
andtrue
operators (answer: we'll apply conditional "truthiness/falsiness" on element-wise comparison results) (resolved in LDM on Feb 5th)bool?
d == tuple
whered
is dynamic and holding a type that has a user-defined comparison operator to tuple typesd1 == d2
whered1
andd2
are dynamic and holding tuple types (that may or may not be comparable statically)Rest
of 1 element orValueTuple'1
in general should be disallowed (they are not tuples)Related SO question