Example #1
0
            private AggCastResult bindExplicitConversionToAggregate(AggregateType aggTypeDest)
            {
                Debug.Assert(_typeSrc != null);
                Debug.Assert(aggTypeDest != null);

                // TypeReference and ArgIterator can't be boxed (or converted to anything else)
                if (_typeSrc.isSpecialByRefType())
                {
                    return(AggCastResult.Abort);
                }

                AggCastResult result = bindExplicitConversionFromEnumToAggregate(aggTypeDest);

                if (result != AggCastResult.Failure)
                {
                    return(result);
                }

                result = bindExplicitConversionToEnum(aggTypeDest);
                if (result != AggCastResult.Failure)
                {
                    return(result);
                }

                result = bindExplicitConversionBetweenSimpleTypes(aggTypeDest);
                if (result != AggCastResult.Failure)
                {
                    return(result);
                }

                result = bindExplicitConversionBetweenAggregates(aggTypeDest);
                if (result != AggCastResult.Failure)
                {
                    return(result);
                }

                result = bindExplicitConversionFromPointerToInt(aggTypeDest);
                if (result != AggCastResult.Failure)
                {
                    return(result);
                }

                if (_typeSrc.IsVoidType())
                {
                    // No conversion is allowed to or from a void type (user defined or otherwise)
                    // This is most likely the result of a failed anonymous method or member group conversion
                    return(AggCastResult.Abort);
                }

                result = bindExplicitConversionFromTypeVarToAggregate(aggTypeDest);
                if (result != AggCastResult.Failure)
                {
                    return(result);
                }

                return(AggCastResult.Failure);
            }
Example #2
0
            private AggCastResult bindExplicitConversionToAggregate(AggregateType aggTypeDest)
            {
                Debug.Assert(_typeSrc != null);
                Debug.Assert(aggTypeDest != null);

                AggCastResult result = bindExplicitConversionFromEnumToAggregate(aggTypeDest);

                if (result != AggCastResult.Failure)
                {
                    return(result);
                }

                result = bindExplicitConversionToEnum(aggTypeDest);
                if (result != AggCastResult.Failure)
                {
                    return(result);
                }

                result = bindExplicitConversionBetweenSimpleTypes(aggTypeDest);
                if (result != AggCastResult.Failure)
                {
                    return(result);
                }

                result = bindExplicitConversionBetweenAggregates(aggTypeDest);
                if (result != AggCastResult.Failure)
                {
                    return(result);
                }

                result = bindExplicitConversionFromPointerToInt(aggTypeDest);
                if (result != AggCastResult.Failure)
                {
                    return(result);
                }

                if (_typeSrc is VoidType)
                {
                    // No conversion is allowed to or from a void type (user defined or otherwise)
                    // This is most likely the result of a failed anonymous method or member group conversion
                    return(AggCastResult.Abort);
                }

                result = bindExplicitConversionFromTypeVarToAggregate(aggTypeDest);
                if (result != AggCastResult.Failure)
                {
                    return(result);
                }

                return(AggCastResult.Failure);
            }
Example #3
0
            /*
             * BindExplicitConversion
             *
             * This is a complex routine with complex parameter. Generally, this should
             * be called through one of the helper methods that insulates you
             * from the complexity of the interface. This routine handles all the logic
             * associated with explicit conversions.
             *
             * Note that this function calls BindImplicitConversion first, so the main
             * logic is only concerned with conversions that can be made explicitly, but
             * not implicitly.
             */
            public bool Bind()
            {
                // To test for a standard conversion, call canConvert(exprSrc, typeDest, STANDARDANDCONVERTTYPE.NOUDC) and
                // canConvert(typeDest, typeSrc, STANDARDANDCONVERTTYPE.NOUDC).
                Debug.Assert((_flags & CONVERTTYPE.STANDARD) == 0);

                // 13.2 Explicit conversions
                //
                // The following conversions are classified as explicit conversions:
                //
                // * All implicit conversions
                // * Explicit numeric conversions
                // * Explicit enumeration conversions
                // * Explicit reference conversions
                // * Explicit interface conversions
                // * Unboxing conversions
                // * Explicit type parameter conversions
                // * User-defined explicit conversions
                // * Explicit nullable conversions
                // * Lifted user-defined explicit conversions
                //
                // Explicit conversions can occur in cast expressions (14.6.6).
                //
                // The explicit conversions that are not implicit conversions are conversions that cannot be
                // proven always to succeed, conversions that are known possibly to lose information, and
                // conversions across domains of types sufficiently different to merit explicit notation.

                // The set of explicit conversions includes all implicit conversions.

                // Don't try user-defined conversions now because we'll try them again later.
                if (_binder.BindImplicitConversion(_exprSrc, _typeSrc, _exprTypeDest, _pDestinationTypeForLambdaErrorReporting, _needsExprDest, out _exprDest, _flags | CONVERTTYPE.ISEXPLICIT))
                {
                    return(true);
                }

                if (_typeSrc == null || _typeDest == null || _typeSrc is ErrorType ||
                    _typeDest is ErrorType || _typeDest.IsNeverSameType())
                {
                    return(false);
                }

                if (_typeDest is NullableType)
                {
                    // This is handled completely by BindImplicitConversion.
                    return(false);
                }

                if (_typeSrc is NullableType)
                {
                    return(bindExplicitConversionFromNub());
                }

                if (bindExplicitConversionFromArrayToIList())
                {
                    return(true);
                }

                // if we were casting an integral constant to another constant type,
                // then, if the constant were in range, then the above call would have succeeded.

                // But it failed, and so we know that the constant is not in range

                switch (_typeDest.GetTypeKind())
                {
                default:
                    VSFAIL("Bad type kind");
                    return(false);

                case TypeKind.TK_VoidType:
                    return(false);    // Can't convert to a method group or anon method.

                case TypeKind.TK_NullType:
                    return(false);     // Can never convert TO the null type.

                case TypeKind.TK_TypeParameterType:
                    if (bindExplicitConversionToTypeVar())
                    {
                        return(true);
                    }
                    break;

                case TypeKind.TK_ArrayType:
                    if (bindExplicitConversionToArray((ArrayType)_typeDest))
                    {
                        return(true);
                    }
                    break;

                case TypeKind.TK_PointerType:
                    if (bindExplicitConversionToPointer())
                    {
                        return(true);
                    }
                    break;

                case TypeKind.TK_AggregateType:
                {
                    AggCastResult result = bindExplicitConversionToAggregate(_typeDest as AggregateType);

                    if (result == AggCastResult.Success)
                    {
                        return(true);
                    }
                    if (result == AggCastResult.Abort)
                    {
                        return(false);
                    }
                    break;
                }
                }

                // No built-in conversion was found. Maybe a user-defined conversion?
                if (0 == (_flags & CONVERTTYPE.NOUDC))
                {
                    return(_binder.bindUserDefinedConversion(_exprSrc, _typeSrc, _typeDest, _needsExprDest, out _exprDest, false));
                }
                return(false);
            }