private bool UpperBoundArrayInference(CType pSource, CType pDest)
{
// SPEC: Otherwise, if V is an array CType Ve[...] and U is an array
// SPEC: CType Ue[...] of the same rank, or if V is a one-dimensional array
// SPEC: CType Ve[] and U is one of IEnumerable<Ue>, ICollection<Ue>,
// SPEC: IList<Ue>, IReadOnlyCollection<Ue> or IReadOnlyList<Ue> then
// SPEC: if Ue is known to be a reference CType then an upper-bound inference
// SPEC: from Ue to Ve is made.
// SPEC: otherwise an exact inference from Ue to Ve is made.
if (!pDest.IsArrayType())
{
return false;
}
ArrayType pArrayDest = pDest.AsArrayType();
CType pElementDest = pArrayDest.GetElementType();
CType pElementSource = null;
if (pSource.IsArrayType())
{
ArrayType pArraySource = pSource.AsArrayType();
if (pArrayDest.rank != pArraySource.rank)
{
return false;
}
pElementSource = pArraySource.GetElementType();
}
else if (pSource.isPredefType(PredefinedType.PT_G_IENUMERABLE) ||
pSource.isPredefType(PredefinedType.PT_G_ICOLLECTION) ||
pSource.isPredefType(PredefinedType.PT_G_ILIST) ||
pSource.isPredefType(PredefinedType.PT_G_IREADONLYLIST) ||
pSource.isPredefType(PredefinedType.PT_G_IREADONLYCOLLECTION))
{
if (pArrayDest.rank != 1)
{
return false;
}
AggregateType pAggregateSource = pSource.AsAggregateType();
pElementSource = pAggregateSource.GetTypeArgsThis().Item(0);
}
else
{
return false;
}
if (pElementSource.IsRefType())
{
UpperBoundInference(pElementSource, pElementDest);
}
else
{
ExactInference(pElementSource, pElementDest);
}
return true;
}