private void UpperBoundInference(CType pSource, CType pDest)
{
// SPEC: An upper-bound inference from a CType U to a CType V is made as follows:
// SPEC: If V is one of the unfixed Xi then U is added to the set of
// SPEC: upper bounds for Xi.
if (UpperBoundTypeParameterInference(pSource, pDest))
{
return;
}
// 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> or
// SPEC: IList<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 (UpperBoundArrayInference(pSource, pDest))
{
return;
}
// SPEC: Otherwise, if V is nullable CType V1? and U is nullable CType U1?
// SPEC: then an exact inference is made from U1 to V1.
if (ExactNullableInference(pSource, pDest))
{
return;
}
// SPEC: Otherwise... cases for constructed types
if (UpperBoundConstructedInference(pSource, pDest))
{
return;
}
// SPEC: Otherwise, no inferences are made.
}