Browse Source

Fixed invalid generic inference from generic constraints

Brian Fiete 4 năm trước cách đây
mục cha
commit
03e28f3add

+ 18 - 0
IDE/Tests/CompileFail001/src/Generics.bf

@@ -85,5 +85,23 @@ namespace IDETest
 		{
 		{
 
 
 		}
 		}
+
+		public static void TestGen<T, TItem>(T val)
+			where T : IEnumerator<TItem>
+			where TItem : var
+		{
+			Console.WriteLine(typeof(decltype(val)).ToString(.. scope .()));
+		}
+
+		public static void TestPreGen<T>()
+		{
+			T a = default;
+			TestGen(a); //FAIL Unable to determine generic argument 'TItem'
+		}
+
+		public static void TestGenBug()
+		{
+			TestPreGen<List<int>>();
+		}
 	}
 	}
 }
 }

+ 13 - 1
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -243,6 +243,16 @@ bool BfGenericInferContext::InferGenericArgument(BfMethodInstance* methodInstanc
 	if (argType == NULL)
 	if (argType == NULL)
 		return false;	
 		return false;	
 	
 	
+	if (mIgnoreMethodGenericParam)
+	{
+		if (argType->IsGenericParam())
+		{
+			auto genericParamType = (BfGenericParamType*)argType;
+			if (genericParamType->mGenericParamKind == BfGenericParamKind_Method)
+				return false;
+		}
+	}
+
 	if (!wantType->IsUnspecializedType())
 	if (!wantType->IsUnspecializedType())
 		return true;
 		return true;
 
 
@@ -623,10 +633,12 @@ bool BfGenericInferContext::InferGenericArguments(BfMethodInstance* methodInstan
 				else
 				else
 					genericParam = mModule->GetGenericParamInstance(genericParamType);
 					genericParam = mModule->GetGenericParamInstance(genericParamType);
 
 
+				// Generic arg references in constraints refer to the caller, not the callee -- so ignore those
+				SetAndRestoreValue<bool> prevIgnoreMethodGenericArg(mIgnoreMethodGenericParam, true);
 				if (genericParam->mTypeConstraint != NULL)
 				if (genericParam->mTypeConstraint != NULL)
 					InferGenericArgument(methodInstance, genericParam->mTypeConstraint, ifaceConstraint, BfIRValue());
 					InferGenericArgument(methodInstance, genericParam->mTypeConstraint, ifaceConstraint, BfIRValue());
 				for (auto argIfaceConstraint : genericParam->mInterfaceConstraints)
 				for (auto argIfaceConstraint : genericParam->mInterfaceConstraints)
-					InferGenericArgument(methodInstance, argIfaceConstraint, ifaceConstraint, BfIRValue());
+					InferGenericArgument(methodInstance, argIfaceConstraint, ifaceConstraint, BfIRValue());				
 			}
 			}
 		}
 		}
 	}
 	}

+ 2 - 0
IDEHelper/Compiler/BfExprEvaluator.h

@@ -138,12 +138,14 @@ public:
 	BfTypeVector* mCheckMethodGenericArguments;
 	BfTypeVector* mCheckMethodGenericArguments;
 	SizedArray<BfIRValue, 4> mPrevArgValues;
 	SizedArray<BfIRValue, 4> mPrevArgValues;
 	int mInferredCount;
 	int mInferredCount;
+	bool mIgnoreMethodGenericParam;
 
 
 public:
 public:
 	BfGenericInferContext()
 	BfGenericInferContext()
 	{
 	{
 		mModule = NULL;
 		mModule = NULL;
 		mInferredCount = 0;
 		mInferredCount = 0;
+		mIgnoreMethodGenericParam = false;
 	}
 	}
 	bool InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue);
 	bool InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue);
 	int GetUnresolvedCount()
 	int GetUnresolvedCount()

+ 2 - 2
IDEHelper/Compiler/BfModule.cpp

@@ -7483,8 +7483,8 @@ String BfModule::GenericParamSourceToString(const BfGenericParamSource & generic
 {
 {
 	if (genericParamSource.mMethodInstance != NULL)
 	if (genericParamSource.mMethodInstance != NULL)
 	{		
 	{		
-		auto methodInst = GetUnspecializedMethodInstance(genericParamSource.mMethodInstance, false);
-		SetAndRestoreValue<BfMethodInstance*> prevMethodInst(methodInst, NULL);
+		//auto methodInst = GetUnspecializedMethodInstance(genericParamSource.mMethodInstance, false);
+		//SetAndRestoreValue<BfMethodInstance*> prevMethodInst(mCurMethodInstance, methodInst);
 		return MethodToString(genericParamSource.mMethodInstance);
 		return MethodToString(genericParamSource.mMethodInstance);
 	}
 	}
 	else
 	else