From 17d2db4cc45d0e22c1a462f0db0a6f59a5c31bd0 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 1 Nov 2021 10:22:28 -0700 Subject: [PATCH] Method selection fix for extern constraints, no ambiguity error for var --- IDEHelper/Compiler/BfExprEvaluator.cpp | 27 ++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 36b71ead..72eac92e 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -1098,11 +1098,11 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp }; _GetParams(0, newMethodInstance); - _GetParams(0, prevMethodInstance); + _GetParams(1, prevMethodInstance); for (auto kv : externConstraints) { - SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(kv.mValue.mParams[0], kv.mValue.mParams[1]), mModule->AreConstraintsSubset(kv.mValue.mParams[1], kv.mValue.mParams[0])); + SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(kv.mValue.mParams[1], kv.mValue.mParams[0]), mModule->AreConstraintsSubset(kv.mValue.mParams[0], kv.mValue.mParams[1])); } if ((isBetter) || (isWorse)) @@ -2176,6 +2176,29 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst // And if neither better nor worse then they are equally good, which is not allowed either if (((!isBetter) && (!isWorse)) || ((isBetter) && (isWorse))) { + if (!mHasVarArguments) + { + // If we are ambiguous based on a subset of an extern 'var' constraint then don't throw an error + auto _CheckMethodInfo = [&](BfMethodInstance* checkMethodInstance) + { + if (checkMethodInstance->mMethodInfoEx == NULL) + return; + for (auto genericParam : checkMethodInstance->mMethodInfoEx->mGenericParams) + { + if ((genericParam->mExternType == NULL) || (!genericParam->mExternType->IsGenericParam())) + continue; + auto genericParamType = (BfGenericParamType*)genericParam->mExternType; + if (genericParamType->mGenericParamKind != BfGenericParamKind_Type) + continue; + auto externGenericParam = mModule->GetGenericParamInstance(genericParamType); + if ((externGenericParam->mGenericParamFlags & BfGenericParamFlag_Var) != 0) + mHasVarArguments = true; + } + }; + _CheckMethodInfo(methodInstance); + _CheckMethodInfo(prevMethodInstance); + } + if (mHasVarArguments) { if (methodInstance->mReturnType != prevMethodInstance->mReturnType)