private bool UpperBoundInterfaceInference(AggregateType pSource, CType pDest)
{
if (!pSource.isInterfaceType())
{
return false;
}
// SPEC: Otherwise, if U is an interface CType C<U1...Uk> and V is a class CType
// SPEC: or struct CType and there is a unique set V1...Vk such that V directly
// SPEC: or indirectly implements C<V1...Vk> then an exact ...
// SPEC: ... and U is an interface CType ...
if (!pDest.isStructType() && !pDest.isClassType() &&
!pDest.isInterfaceType())
{
return false;
}
var interfaces = pDest.AllPossibleInterfaces();
AggregateType pInterface = null;
foreach (AggregateType pCurrent in interfaces)
{
if (pCurrent.GetOwningAggregate() == pSource.GetOwningAggregate())
{
if (pInterface == null)
{
pInterface = pCurrent;
}
else if (pInterface != pCurrent)
{
// Not unique. Bail out.
return false;
}
}
}
if (pInterface == null)
{
return false;
}
UpperBoundTypeArgumentInference(pInterface, pDest.AsAggregateType());
return true;
}