diff --git a/IDE/Tests/CompileFail001/src/Generics.bf b/IDE/Tests/CompileFail001/src/Generics.bf index d896a9fc..8a27fbf4 100644 --- a/IDE/Tests/CompileFail001/src/Generics.bf +++ b/IDE/Tests/CompileFail001/src/Generics.bf @@ -85,5 +85,23 @@ namespace IDETest { } + + public static void TestGen(T val) + where T : IEnumerator + where TItem : var + { + Console.WriteLine(typeof(decltype(val)).ToString(.. scope .())); + } + + public static void TestPreGen() + { + T a = default; + TestGen(a); //FAIL Unable to determine generic argument 'TItem' + } + + public static void TestGenBug() + { + TestPreGen>(); + } } } diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index b2433bca..81d47c40 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -243,6 +243,16 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc if (argType == NULL) return false; + if (mIgnoreMethodGenericParam) + { + if (argType->IsGenericParam()) + { + auto genericParamType = (BfGenericParamType*)argType; + if (genericParamType->mGenericParamKind == BfGenericParamKind_Method) + return false; + } + } + if (!wantType->IsUnspecializedType()) return true; @@ -623,10 +633,12 @@ bool BfGenericInferContext::InferGenericArguments(BfMethodInstance* methodInstan else genericParam = mModule->GetGenericParamInstance(genericParamType); + // Generic arg references in constraints refer to the caller, not the callee -- so ignore those + SetAndRestoreValue prevIgnoreMethodGenericArg(mIgnoreMethodGenericParam, true); if (genericParam->mTypeConstraint != NULL) InferGenericArgument(methodInstance, genericParam->mTypeConstraint, ifaceConstraint, BfIRValue()); for (auto argIfaceConstraint : genericParam->mInterfaceConstraints) - InferGenericArgument(methodInstance, argIfaceConstraint, ifaceConstraint, BfIRValue()); + InferGenericArgument(methodInstance, argIfaceConstraint, ifaceConstraint, BfIRValue()); } } } diff --git a/IDEHelper/Compiler/BfExprEvaluator.h b/IDEHelper/Compiler/BfExprEvaluator.h index 6eb98707..95b26958 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.h +++ b/IDEHelper/Compiler/BfExprEvaluator.h @@ -138,12 +138,14 @@ public: BfTypeVector* mCheckMethodGenericArguments; SizedArray mPrevArgValues; int mInferredCount; + bool mIgnoreMethodGenericParam; public: BfGenericInferContext() { mModule = NULL; mInferredCount = 0; + mIgnoreMethodGenericParam = false; } bool InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue); int GetUnresolvedCount() diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 66ef6ff4..4dc7187b 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -7483,8 +7483,8 @@ String BfModule::GenericParamSourceToString(const BfGenericParamSource & generic { if (genericParamSource.mMethodInstance != NULL) { - auto methodInst = GetUnspecializedMethodInstance(genericParamSource.mMethodInstance, false); - SetAndRestoreValue prevMethodInst(methodInst, NULL); + //auto methodInst = GetUnspecializedMethodInstance(genericParamSource.mMethodInstance, false); + //SetAndRestoreValue prevMethodInst(mCurMethodInstance, methodInst); return MethodToString(genericParamSource.mMethodInstance); } else