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