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); }
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); }
/* * 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); }