private bool UpperBoundConstructedInference(CType pSource, CType pDest)
{
if (!pSource.IsAggregateType())
{
return false;
}
AggregateType pConstructedSource = pSource.AsAggregateType();
TypeArray pSourceArgs = pConstructedSource.GetTypeArgsAll();
if (pSourceArgs.size == 0)
{
return false;
}
// SPEC: Otherwise, if V is a constructed CType C<V1...Vk> and U is
// SPEC: C<U1...Uk> then an exact inference,
// SPEC: lower bound inference or upper bound inference
// SPEC: is made from each Ui to the corresponding Vi.
if (pDest.IsAggregateType() &&
pConstructedSource.GetOwningAggregate() == pDest.AsAggregateType().GetOwningAggregate())
{
if (pDest.isInterfaceType() || pDest.isDelegateType())
{
UpperBoundTypeArgumentInference(pConstructedSource, pDest.AsAggregateType());
}
else
{
ExactTypeArgumentInference(pConstructedSource, pDest.AsAggregateType());
}
return true;
}
// SPEC: Otherwise, if U is a class CType C<U1...Uk> and V is a class CType which
// SPEC: inherits directly or indirectly from C<V1...Vk> then an exact ...
if (UpperBoundClassInference(pConstructedSource, pDest))
{
return true;
}
// 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 (UpperBoundInterfaceInference(pConstructedSource, pDest))
{
return true;
}
return false;
}