@@ -700,8 +700,24 @@ Expression ParseComparisonOperator()
700
700
}
701
701
else
702
702
{
703
- CheckAndPromoteOperands ( isEquality ? typeof ( IEqualitySignatures ) : typeof ( IRelationalSignatures ) ,
704
- op . Text , ref left , ref right , op . Pos ) ;
703
+ bool typesAreSameAndImplementCorrectInterface = false ;
704
+ if ( left . Type == right . Type )
705
+ {
706
+ var interfaces = left . Type . GetInterfaces ( ) . Where ( x => x . GetTypeInfo ( ) . IsGenericType ) ;
707
+ if ( isEquality )
708
+ {
709
+ typesAreSameAndImplementCorrectInterface = interfaces . Any ( x => x . GetGenericTypeDefinition ( ) == typeof ( IEquatable < > ) ) ;
710
+ }
711
+ else
712
+ {
713
+ typesAreSameAndImplementCorrectInterface = interfaces . Any ( x => x . GetGenericTypeDefinition ( ) == typeof ( IComparable < > ) ) ;
714
+ }
715
+ }
716
+
717
+ if ( ! typesAreSameAndImplementCorrectInterface )
718
+ {
719
+ CheckAndPromoteOperands ( isEquality ? typeof ( IEqualitySignatures ) : typeof ( IRelationalSignatures ) , op . Text , ref left , ref right , op . Pos ) ;
720
+ }
705
721
}
706
722
707
723
switch ( op . Id )
@@ -1551,6 +1567,7 @@ static Type FindGenericType(Type generic, Type type)
1551
1567
{
1552
1568
if ( type . GetTypeInfo ( ) . IsGenericType && type . GetGenericTypeDefinition ( ) == generic )
1553
1569
return type ;
1570
+
1554
1571
if ( generic . GetTypeInfo ( ) . IsInterface )
1555
1572
{
1556
1573
foreach ( Type intfType in type . GetInterfaces ( ) )
@@ -1559,8 +1576,10 @@ static Type FindGenericType(Type generic, Type type)
1559
1576
if ( found != null ) return found ;
1560
1577
}
1561
1578
}
1579
+
1562
1580
type = type . GetTypeInfo ( ) . BaseType ;
1563
1581
}
1582
+
1564
1583
return null ;
1565
1584
}
1566
1585
@@ -1843,9 +1862,12 @@ static bool IsEnumType(Type type)
1843
1862
void CheckAndPromoteOperand ( Type signatures , string opName , ref Expression expr , int errorPos )
1844
1863
{
1845
1864
Expression [ ] args = { expr } ;
1865
+
1846
1866
MethodBase method ;
1847
1867
if ( FindMethod ( signatures , "F" , false , args , out method ) != 1 )
1848
- throw ParseError ( errorPos , Res . IncompatibleOperand , opName , GetTypeName ( args [ 0 ] . Type ) ) ;
1868
+ {
1869
+ throw IncompatibleOperandError ( opName , expr , errorPos ) ;
1870
+ }
1849
1871
1850
1872
expr = args [ 0 ] ;
1851
1873
}
@@ -1864,9 +1886,14 @@ void CheckAndPromoteOperands(Type signatures, string opName, ref Expression left
1864
1886
right = args [ 1 ] ;
1865
1887
}
1866
1888
1867
- static Exception IncompatibleOperandsError ( string opName , Expression left , Expression right , int pos )
1889
+ static Exception IncompatibleOperandError ( string opName , Expression expr , int errorPos )
1868
1890
{
1869
- return ParseError ( pos , Res . IncompatibleOperands , opName , GetTypeName ( left . Type ) , GetTypeName ( right . Type ) ) ;
1891
+ return ParseError ( errorPos , Res . IncompatibleOperand , opName , GetTypeName ( expr . Type ) ) ;
1892
+ }
1893
+
1894
+ static Exception IncompatibleOperandsError ( string opName , Expression left , Expression right , int errorPos )
1895
+ {
1896
+ return ParseError ( errorPos , Res . IncompatibleOperands , opName , GetTypeName ( left . Type ) , GetTypeName ( right . Type ) ) ;
1870
1897
}
1871
1898
1872
1899
static MemberInfo FindPropertyOrField ( Type type , string memberName , bool staticAccess )
@@ -2107,8 +2134,10 @@ Expression PromoteExpression(Expression expr, Type type, bool exact, bool conver
2107
2134
2108
2135
if ( IsCompatibleWith ( expr . Type , type ) )
2109
2136
{
2110
- if ( type . GetTypeInfo ( ) . IsValueType || exact || ( expr . Type . GetTypeInfo ( ) . IsValueType && convertExpr ) )
2137
+ if ( type . GetTypeInfo ( ) . IsValueType || exact || expr . Type . GetTypeInfo ( ) . IsValueType && convertExpr )
2138
+ {
2111
2139
return Expression . Convert ( expr , type ) ;
2140
+ }
2112
2141
2113
2142
return expr ;
2114
2143
}
0 commit comments