/// <summary> /// Returns the better type amongst the two, with some possible modifications (dynamic/object or tuple names). /// </summary> private TypeSymbol Better(TypeSymbol type1, TypeSymbol type2, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { // Anything is better than an error sym. if (type1.IsErrorType()) { return(type2); } if ((object)type2 == null || type2.IsErrorType()) { return(type1); } var t1tot2 = _conversions.ClassifyImplicitConversionFromType(type1, type2, ref useSiteDiagnostics).Exists; var t2tot1 = _conversions.ClassifyImplicitConversionFromType(type2, type1, ref useSiteDiagnostics).Exists; if (t1tot2 && t2tot1) { if (type1.IsDynamic()) { return(type1); } if (type2.IsDynamic()) { return(type2); } if (type1.Equals(type2, TypeCompareKind.IgnoreDynamicAndTupleNames)) { return(MethodTypeInferrer.MergeTupleNames(type1, type2, MethodTypeInferrer.MergeDynamic(type1, type2, type1, _conversions.CorLibrary), _conversions.CorLibrary)); } return(null); } if (t1tot2) { return(type2); } if (t2tot1) { return(type1); } return(null); }