private AggCastResult bindExplicitConversionBetweenAggregates(AggregateType aggTypeDest)
{
// 13.2.3
//
// The explicit reference conversions are:
//
// * From object to any reference-type.
// * From any class-type S to any class-type T, provided S is a base class of T.
// * From any class-type S to any interface-type T, provided S is not sealed and
// provided S does not implement T.
// * From any interface-type S to any class-type T, provided T is not sealed or provided
// T implements S.
// * From any interface-type S to any interface-type T, provided S is not derived from T.
Debug.Assert(_typeSrc != null);
Debug.Assert(aggTypeDest != null);
if (!(_typeSrc is AggregateType atSrc))
{
return(AggCastResult.Failure);
}
AggregateSymbol aggSrc = atSrc.getAggregate();
AggregateSymbol aggDest = aggTypeDest.getAggregate();
if (GetSymbolLoader().HasBaseConversion(aggTypeDest, atSrc))
{
if (_needsExprDest)
{
if (aggDest.IsValueType() && aggSrc.getThisType().fundType() == FUNDTYPE.FT_REF)
{
_binder.bindSimpleCast(_exprSrc, _exprTypeDest, out _exprDest, EXPRFLAG.EXF_UNBOX);
}
else
{
_binder.bindSimpleCast(_exprSrc, _exprTypeDest, out _exprDest, EXPRFLAG.EXF_REFCHECK | (_exprSrc?.Flags & EXPRFLAG.EXF_CANTBENULL ?? 0));
}
}
return(AggCastResult.Success);
}
if ((aggSrc.IsClass() && !aggSrc.IsSealed() && aggDest.IsInterface()) ||
(aggSrc.IsInterface() && aggDest.IsClass() && !aggDest.IsSealed()) ||
(aggSrc.IsInterface() && aggDest.IsInterface()) ||
CConversions.HasGenericDelegateExplicitReferenceConversion(GetSymbolLoader(), _typeSrc, aggTypeDest))
{
if (_needsExprDest)
{
_binder.bindSimpleCast(_exprSrc, _exprTypeDest, out _exprDest, EXPRFLAG.EXF_REFCHECK | (_exprSrc?.Flags & EXPRFLAG.EXF_CANTBENULL ?? 0));
}
return(AggCastResult.Success);
}
return(AggCastResult.Failure);
}