private void UpperBoundTypeArgumentInference(
AggregateType pSource, AggregateType pDest)
{
// SPEC: The choice of inference for the i-th CType argument is made
// SPEC: based on the declaration of the i-th CType parameter of C, as
// SPEC: follows:
// SPEC: if Ui is known to be of reference CType and the i-th CType parameter
// SPEC: was declared as covariant then an upper-bound inference is made.
// SPEC: if Ui is known to be of reference CType and the i-th CType parameter
// SPEC: was declared as contravariant then a lower-bound inference is made.
// SPEC: otherwise, an exact inference is made.
Debug.Assert(pSource != null);
Debug.Assert(pDest != null);
Debug.Assert(pSource.GetOwningAggregate() == pDest.GetOwningAggregate());
TypeArray pTypeParams = pSource.GetOwningAggregate().GetTypeVarsAll();
TypeArray pSourceArgs = pSource.GetTypeArgsAll();
TypeArray pDestArgs = pDest.GetTypeArgsAll();
Debug.Assert(pTypeParams != null);
Debug.Assert(pSourceArgs != null);
Debug.Assert(pDestArgs != null);
Debug.Assert(pTypeParams.size == pSourceArgs.size);
Debug.Assert(pTypeParams.size == pDestArgs.size);
for (int arg = 0; arg < pSourceArgs.size; ++arg)
{
TypeParameterType pTypeParam = pTypeParams.ItemAsTypeParameterType(arg);
CType pSourceArg = pSourceArgs.Item(arg);
CType pDestArg = pDestArgs.Item(arg);
if (pSourceArg.IsRefType() && pTypeParam.Covariant)
{
UpperBoundInference(pSourceArg, pDestArg);
}
else if (pSourceArg.IsRefType() && pTypeParam.Contravariant)
{
LowerBoundInference(pSourceArgs.Item(arg), pDestArgs.Item(arg));
}
else
{
ExactInference(pSourceArgs.Item(arg), pDestArgs.Item(arg));
}
}
}