/// <summary> /// Make exact inference from U to V. /// C# 4.0 spec: §7.5.2.8 Exact inferences /// </summary> void MakeExactInference(IType U, IType V) { Log.WriteLine("MakeExactInference from " + U + " to " + V); // If V is one of the unfixed Xi then U is added to the set of bounds for Xi. TP tp = GetTPForType(V); if (tp != null && tp.IsFixed == false) { Log.WriteLine(" Add exact bound '" + U + "' to " + tp); tp.AddExactBound(U); return; } if (U is ByReferenceType brU && V is ByReferenceType brV) { MakeExactInference(brU.ElementType, brV.ElementType); return; } if (U is ArrayType arrU && V is ArrayType arrV && arrU.Dimensions == arrV.Dimensions) { MakeExactInference(arrU.ElementType, arrV.ElementType); return; } if (U is ParameterizedType pU && V is ParameterizedType pV && object.Equals(pU.GetDefinition(), pV.GetDefinition()) && pU.TypeParameterCount == pV.TypeParameterCount) { Log.Indent(); for (int i = 0; i < pU.TypeParameterCount; i++) { MakeExactInference(pU.GetTypeArgument(i), pV.GetTypeArgument(i)); } Log.Unindent(); } }
/// <summary> /// Make exact inference from U to V. /// C# 4.0 spec: §7.5.2.8 Exact inferences /// </summary> void MakeExactInference(IType U, IType V) { Log.WriteLine("MakeExactInference from " + U + " to " + V); if (U.Nullability == V.Nullability) { U = U.WithoutNullability(); V = V.WithoutNullability(); } // If V is one of the unfixed Xi then U is added to the set of bounds for Xi. TP tp = GetTPForType(V); if (tp != null && tp.IsFixed == false) { Log.WriteLine(" Add exact bound '" + U + "' to " + tp); tp.AddExactBound(U); return; } // Handle by reference types: ByReferenceType brU = U as ByReferenceType; ByReferenceType brV = V as ByReferenceType; if (brU != null && brV != null) { MakeExactInference(brU.ElementType, brV.ElementType); return; } // Handle array types: ArrayType arrU = U as ArrayType; ArrayType arrV = V as ArrayType; if (arrU != null && arrV != null && arrU.Dimensions == arrV.Dimensions) { MakeExactInference(arrU.ElementType, arrV.ElementType); return; } // Handle parameterized type: ParameterizedType pU = U.TupleUnderlyingTypeOrSelf() as ParameterizedType; ParameterizedType pV = V.TupleUnderlyingTypeOrSelf() as ParameterizedType; if (pU != null && pV != null && object.Equals(pU.GenericType, pV.GenericType) && pU.TypeParameterCount == pV.TypeParameterCount) { Log.Indent(); for (int i = 0; i < pU.TypeParameterCount; i++) { MakeExactInference(pU.GetTypeArgument(i), pV.GetTypeArgument(i)); } Log.Unindent(); } }
/// <summary> /// Make exact inference from U to V. /// V# 4.0 spec: §7.5.2.8 Exact inferences /// </summary> void MakeExactInference(IType U, IType V) { // If V is one of the unfixed Xi then U is added to the set of bounds for Xi. TP tp = GetTPForType(V); if (tp != null && tp.IsFixed == false) { tp.AddExactBound(U); return; } // Handle by reference types: ByReferenceType brU = U as ByReferenceType; ByReferenceType brV = V as ByReferenceType; if (brU != null && brV != null) { MakeExactInference(brU.ElementType, brV.ElementType); return; } // Handle array types: ArrayType arrU = U as ArrayType; ArrayType arrV = V as ArrayType; if (arrU != null && arrV != null && arrU.Dimensions == arrV.Dimensions) { MakeExactInference(arrU.ElementType, arrV.ElementType); return; } // Handle parameterized type: ParameterizedTypeSpec pU = U as ParameterizedTypeSpec; ParameterizedTypeSpec pV = V as ParameterizedTypeSpec; if (pU != null && pV != null && object.Equals(pU.GetDefinition(), pV.GetDefinition()) && pU.TypeParameterCount == pV.TypeParameterCount) { for (int i = 0; i < pU.TypeParameterCount; i++) { MakeExactInference(pU.GetTypeArgument(i), pV.GetTypeArgument(i)); } } }