@@ -2505,9 +2505,57 @@ private bool TryGetOverloadedImplicitOperator(TokenId tokenId, ref Expression le
25052505 return overloadedImplicitOperatorFound ;
25062506 }
25072507
2508+ private bool TryGetOverloadedExplicitOperator ( TokenId tokenId , ref Expression left , ref Expression right )
2509+ {
2510+ const string methodName = "op_Explicit" ;
2511+ //if (tokenId is not (TokenId.Ampersand or TokenId.DoubleAmpersand or TokenId.Bar or TokenId.DoubleBar))
2512+ //{
2513+ // return false;
2514+ //}
2515+
2516+ Expression ? expression = null ;
2517+ var overloadedExplicitOperatorFound = false ;
2518+
2519+ // Try to find the "op_Explicit" method on the left which takes the left as parameter and returns the type.
2520+ var leftType = left . Type ;
2521+ var isNullableLeftType = TypeHelper . TryGetNonNullableType ( leftType , out var nonNullableLeftType ) ;
2522+ var args = new [ ] { left } ;
2523+ if ( _methodFinder . FindMethod ( leftType , methodName , true , ref expression , ref args , out var methodBaseLeft ) > 0 && methodBaseLeft is MethodInfo methodInfoLeft && methodInfoLeft . ReturnType == nonNullableLeftType )
2524+ {
2525+ //if (isNullableLeftType)
2526+ //{
2527+ // left = Expression.Convert(left, leftType);
2528+ //}
2529+ //left = Expression.Call(methodInfoLeft, left);
2530+
2531+ left = Expression . Convert ( left , nonNullableLeftType , methodInfoLeft ) ;
2532+
2533+ overloadedExplicitOperatorFound = true ;
2534+ }
2535+
2536+ // Try to find the "op_Explicit" method on the right which takes the right as parameter and returns the type.
2537+ var rightType = right . Type ;
2538+ var rightTypeIsNullable = TypeHelper . TryGetNonNullableType ( rightType , out var nonNullableRightType ) ;
2539+ var argsRight = new [ ] { right } ;
2540+ if ( _methodFinder . FindMethod ( rightType , methodName , true , ref expression , ref argsRight , out var methodBaseRight ) > 0 && methodBaseRight is MethodInfo methodInfoRight && methodInfoRight . ReturnType == nonNullableRightType )
2541+ {
2542+ //if (rightTypeIsNullable)
2543+ //{
2544+ // right = Expression.Convert(right, rightType);
2545+ //}
2546+ //right = Expression.Call(methodInfoRight, right);
2547+
2548+ right = Expression . Convert ( right , nonNullableRightType , methodInfoRight ) ;
2549+
2550+ overloadedExplicitOperatorFound = true ;
2551+ }
2552+
2553+ return overloadedExplicitOperatorFound ;
2554+ }
2555+
25082556 private void CheckAndPromoteOperands ( Type signatures , TokenId opId , string opName , ref Expression left , ref Expression right , int errorPos )
25092557 {
2510- Expression [ ] args = { left , right } ;
2558+ Expression [ ] args = [ left , right ] ;
25112559
25122560 // 1. Try to find the Equality/Inequality operator
25132561 // 2. Try to find the method with the given signature
@@ -2525,6 +2573,12 @@ private void CheckAndPromoteOperands(Type signatures, TokenId opId, string opNam
25252573 return ;
25262574 }
25272575
2576+ // 4. Try to find the Explicit operator
2577+ if ( TryGetOverloadedExplicitOperator ( opId , ref left , ref right ) )
2578+ {
2579+ return ;
2580+ }
2581+
25282582 throw IncompatibleOperandsError ( opName , left , right , errorPos ) ;
25292583 }
25302584
0 commit comments